2.5: merge with trunk, previous merge was only up to yesterday.
authorBrecht Van Lommel <brechtvanlommel@pandora.be>
Wed, 12 Nov 2008 22:03:11 +0000 (22:03 +0000)
committerBrecht Van Lommel <brechtvanlommel@pandora.be>
Wed, 12 Nov 2008 22:03:11 +0000 (22:03 +0000)
svn merge https://svn.blender.org/svnroot/bf-blender/trunk/blender -r17416:HEAD

47 files changed:
1  2 
SConstruct
config/win32-mingw-config.py
config/win32-vc-config.py
projectfiles_vc9/blender/nodes/nodes.vcproj
source/Makefile
source/blender/blenkernel/BKE_node.h
source/blender/blenkernel/intern/library.c
source/blender/blenkernel/intern/material.c
source/blender/blenkernel/intern/node.c
source/blender/blenkernel/intern/texture.c
source/blender/blenloader/intern/readfile.c
source/blender/blenloader/intern/writefile.c
source/blender/makesdna/DNA_node_types.h
source/blender/makesdna/DNA_texture_types.h
source/blender/nodes/Makefile
source/blender/nodes/SConscript
source/blender/nodes/TEX_node.h
source/blender/nodes/intern/SHD_nodes/SHD_texture.c
source/blender/nodes/intern/SHD_util.c
source/blender/nodes/intern/TEX_nodes/Makefile
source/blender/nodes/intern/TEX_nodes/TEX_bricks.c
source/blender/nodes/intern/TEX_nodes/TEX_checker.c
source/blender/nodes/intern/TEX_nodes/TEX_curves.c
source/blender/nodes/intern/TEX_nodes/TEX_hueSatVal.c
source/blender/nodes/intern/TEX_nodes/TEX_image.c
source/blender/nodes/intern/TEX_nodes/TEX_invert.c
source/blender/nodes/intern/TEX_nodes/TEX_math.c
source/blender/nodes/intern/TEX_nodes/TEX_mixRgb.c
source/blender/nodes/intern/TEX_nodes/TEX_output.c
source/blender/nodes/intern/TEX_nodes/TEX_proc.c
source/blender/nodes/intern/TEX_nodes/TEX_rotate.c
source/blender/nodes/intern/TEX_nodes/TEX_texture.c
source/blender/nodes/intern/TEX_nodes/TEX_translate.c
source/blender/nodes/intern/TEX_nodes/TEX_valToRgb.c
source/blender/nodes/intern/TEX_nodes/TEX_viewer.c
source/blender/nodes/intern/TEX_util.c
source/blender/nodes/intern/TEX_util.h
source/blender/render/extern/include/RE_shader_ext.h
source/blender/render/intern/include/pixelshading.h
source/blender/render/intern/include/texture.h
source/blender/render/intern/source/convertblender.c
source/blender/render/intern/source/pixelshading.c
source/blender/render/intern/source/rayshade.c
source/blender/render/intern/source/rendercore.c
source/blender/render/intern/source/texture.c
tools/Blender.py
tools/btools.py

diff --cc SConstruct
index f27fc8cd7fb36029dfe144b1b7ce74bd5d09d9ed,f27fc8cd7fb36029dfe144b1b7ce74bd5d09d9ed..59152cdc9f3a5fd8d67bc6aca797c702ebd65067
@@@ -516,24 -516,24 +516,21 @@@ else
  
  if env['OURPLATFORM'] in ('win32-vc', 'win32-mingw'):
        dllsources = ['${LCGDIR}/gettext/lib/gnu_gettext.dll',
--                                              '${LCGDIR}/png/lib/libpng.dll',
--                                              '#release/windows/extra/zlib.pyd',
--                                              '${LCGDIR}/zlib/lib/zlib.dll',
--                                              '${LCGDIR}/tiff/lib/libtiff.dll']
++                                              '${BF_PNG_LIBPATH}/libpng.dll',
++                                              '${BF_ZLIB_LIBPATH}/zlib.dll',
++                                              '${BF_TIFF_LIBPATH}/${BF_TIFF_LIB}.dll']
++      dllsources += ['${BF_PTHREADS_LIBPATH}/${BF_PTHREADS_LIB}.dll']
        if env['WITH_BF_SDL']:
--              dllsources.append('${LCGDIR}/sdl/lib/SDL.dll')
++              dllsources.append('${BF_SDL_LIBPATH}/SDL.dll')
        if env['WITH_BF_PYTHON']:
                dllsources.append('#release/windows/extra/python25.zip')
++              dllsources.append('#release/windows/extra/zlib.pyd')
                if env['BF_DEBUG']:
--                      dllsources.append('${LCGDIR}/python/lib/${BF_PYTHON_LIB}_d.dll')
++                      dllsources.append('${BF_PYTHON_LIBPATH}/${BF_PYTHON_LIB}_d.dll')
                else:
--                      dllsources.append('${LCGDIR}/python/lib/${BF_PYTHON_LIB}.dll')
--      if env['OURPLATFORM'] == 'win32-mingw':
--              dllsources += ['${LCGDIR}/pthreads/lib/pthreadGC2.dll']
--      else:
--              dllsources += ['${LCGDIR}/pthreads/lib/pthreadVC2.dll']
++                      dllsources.append('${BF_PYTHON_LIBPATH}/${BF_PYTHON_LIB}.dll')
        if env['WITH_BF_ICONV']:
--              dllsources += ['${LCGDIR}/iconv/lib/iconv.dll']
++              dllsources += ['${BF_ICONV_LIBPATH}/iconv.dll']
        if env['WITH_BF_FFMPEG']:
                dllsources += ['${LCGDIR}/ffmpeg/lib/avcodec-51.dll',
                                                '${LCGDIR}/ffmpeg/lib/avformat-52.dll',
index 15bfce80f8926906e0928a000b5fcbf48adbe85f,15bfce80f8926906e0928a000b5fcbf48adbe85f..22666851f289f552490f78c9f5d504f60425506c
@@@ -9,7 -9,7 +9,7 @@@ BF_PYTHON_VERSION = '2.5
  BF_PYTHON_INC = '${BF_PYTHON}/include/python${BF_PYTHON_VERSION}'
  BF_PYTHON_BINARY = 'python'
  BF_PYTHON_LIB = 'python25'
--BF_PYTHON_LIBPATH = '${BF_PYTHON}/lib'
++BF_PYTHON_LIBPATH = '${BF_PYTHON}/lib/lib25_vs2005'
  
  WITH_BF_OPENAL = True
  WITH_BF_STATICOPENAL = False
@@@ -64,6 -64,6 +64,8 @@@ BF_PNG_LIBPATH = '${BF_PNG}/lib
  
  BF_TIFF = LIBDIR + '/tiff'
  BF_TIFF_INC = '${BF_TIFF}/include'
++BF_TIFF_LIB = 'libtiff'
++BF_TIFF_LIBPATH = '${BF_TIFF}/lib'
  
  WITH_BF_ZLIB = True
  BF_ZLIB = LIBDIR + '/zlib'
index 9a41f7ee55745910930efd29663bca94e4f9f6f6,9a41f7ee55745910930efd29663bca94e4f9f6f6..fe51abe0a89300bbf1c0ee342c41bb6ebc6c1f38
@@@ -77,6 -77,6 +77,8 @@@ BF_PNG_LIBPATH = '${BF_PNG}/lib
  
  BF_TIFF = LIBDIR + '/tiff'
  BF_TIFF_INC = '${BF_TIFF}/include'
++BF_TIFF_LIB = 'libtiff'
++BF_TIFF_LIBPATH = '${BF_TIFF}/lib'
  
  WITH_BF_ZLIB = True
  BF_ZLIB = LIBDIR + '/zlib'
index 90595a41e5a48f0307ce28e466ef7eab59b1fdee,90595a41e5a48f0307ce28e466ef7eab59b1fdee..d32ef98da2fc5a4304e41b080fcc3336155bab1f
                                RelativePath="..\..\..\source\blender\nodes\intern\SHD_util.c"\r
                                >\r
                        </File>\r
++                      <File\r
++                              RelativePath="..\..\..\source\blender\nodes\intern\TEX_util.c"\r
++                              >\r
++                      </File>\r
                        <Filter\r
                                Name="CMP_nodes"\r
                                >\r
                                        >\r
                                </File>\r
                        </Filter>\r
++                      <Filter\r
++                              Name="TEX_nodes"\r
++                              >\r
++                              <File\r
++                                      RelativePath="..\..\..\source\blender\nodes\intern\TEX_nodes\TEX_bricks.c"\r
++                                      >\r
++                              </File>\r
++                              <File\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_curves.c"\r
++                                      >\r
++                              </File>\r
++                              <File\r
++                                      RelativePath="..\..\..\source\blender\nodes\intern\TEX_nodes\TEX_hueSatVal.c"\r
++                                      >\r
++                              </File>\r
++                              <File\r
++                                      RelativePath="..\..\..\source\blender\nodes\intern\TEX_nodes\TEX_image.c"\r
++                                      >\r
++                              </File>\r
++                              <File\r
++                                      RelativePath="..\..\..\source\blender\nodes\intern\TEX_nodes\TEX_invert.c"\r
++                                      >\r
++                              </File>\r
++                              <File\r
++                                      RelativePath="..\..\..\source\blender\nodes\intern\TEX_nodes\TEX_math.c"\r
++                                      >\r
++                              </File>\r
++                              <File\r
++                                      RelativePath="..\..\..\source\blender\nodes\intern\TEX_nodes\TEX_mixRgb.c"\r
++                                      >\r
++                              </File>\r
++                              <File\r
++                                      RelativePath="..\..\..\source\blender\nodes\intern\TEX_nodes\TEX_output.c"\r
++                                      >\r
++                              </File>\r
++                              <File\r
++                                      RelativePath="..\..\..\source\blender\nodes\intern\TEX_nodes\TEX_proc.c"\r
++                                      >\r
++                              </File>\r
++                              <File\r
++                                      RelativePath="..\..\..\source\blender\nodes\intern\TEX_nodes\TEX_rotate.c"\r
++                                      >\r
++                              </File>\r
++                              <File\r
++                                      RelativePath="..\..\..\source\blender\nodes\intern\TEX_nodes\TEX_texture.c"\r
++                                      >\r
++                              </File>\r
++                              <File\r
++                                      RelativePath="..\..\..\source\blender\nodes\intern\TEX_nodes\TEX_translate.c"\r
++                                      >\r
++                              </File>\r
++                              <File\r
++                                      RelativePath="..\..\..\source\blender\nodes\intern\TEX_nodes\TEX_valToRgb.c"\r
++                                      >\r
++                              </File>\r
++                              <File\r
++                                      RelativePath="..\..\..\source\blender\nodes\intern\TEX_nodes\TEX_viewer.c"\r
++                                      >\r
++                              </File>\r
++                      </Filter>\r
                </Filter>\r
                <Filter\r
                        Name="Header Files"\r
                                RelativePath="..\..\..\source\blender\nodes\SHD_node.h"\r
                                >\r
                        </File>\r
++                      <File\r
++                              RelativePath="..\..\..\source\blender\nodes\TEX_node.h"\r
++                              >\r
++                      </File>\r
                        <Filter\r
                                Name="intern"\r
                                >\r
                                        RelativePath="..\..\..\source\blender\nodes\intern\SHD_util.h"\r
                                        >\r
                                </File>\r
++                              <File\r
++                                      RelativePath="..\..\..\source\blender\nodes\intern\TEX_util.h"\r
++                                      >\r
++                              </File>\r
                        </Filter>\r
                </Filter>\r
        </Files>\r
diff --cc source/Makefile
index 18c2da6b4c39e84cd90b1a68a50c82c0b0ee3d8d,558a844eca790df8d58096d6b7f3e663e45f54cd..b0182ff131d352ed2cb5234ddfc85d6ecb7dc326
@@@ -96,6 -97,6 +96,7 @@@ COMLIB += $(OCGDIR)/blender/blenloader/
  COMLIB += $(OCGDIR)/blender/blenpluginapi/$(DEBUG_DIR)libblenpluginapi.a
  COMLIB += $(OCGDIR)/blender/nodes_shd/$(DEBUG_DIR)libnodes_shd.a
  COMLIB += $(OCGDIR)/blender/nodes_cmp/$(DEBUG_DIR)libnodes_cmp.a
++COMLIB += $(OCGDIR)/blender/nodes_tex/$(DEBUG_DIR)libnodes_tex.a
  COMLIB += $(OCGDIR)/blender/nodes/$(DEBUG_DIR)libnodes.a
  COMLIB += $(OCGDIR)/blender/imbuf/$(DEBUG_DIR)libimbuf.a
  COMLIB += $(OCGDIR)/blender/blenlib/$(DEBUG_DIR)libblenlib.a
index 01c54663c6d9e34b43a62eecd9d7a09ad40448b7,01c54663c6d9e34b43a62eecd9d7a09ad40448b7..fa3a654c1c271572c096b517d859716061ac97cf
@@@ -47,6 -47,6 +47,7 @@@ struct rctf
  struct ListBase;
  struct RenderData;
  struct Scene;
++struct Tex;
  struct GPUMaterial;
  struct GPUNode;
  struct GPUNodeStack;
@@@ -118,6 -118,6 +119,8 @@@ typedef struct bNodeType 
  #define NODE_CLASS_MATTE              9
  #define NODE_CLASS_DISTORT            10
  #define NODE_CLASS_OP_DYNAMIC 11
++#define NODE_CLASS_PATTERN 12
++#define NODE_CLASS_TEXTURE 13
  
  /* ************** GENERIC API, TREES *************** */
  
@@@ -377,6 -377,6 +380,45 @@@ void ntreeCompositForceHidden(struct bN
  
  void free_compbuf(struct CompBuf *cbuf); /* internal...*/
  
++
++/* ************** TEXTURE NODES *************** */
++
++struct TexResult;
++
++#define TEX_NODE_OUTPUT     101
++#define TEX_NODE_CHECKER    102
++#define TEX_NODE_TEXTURE    103
++#define TEX_NODE_BRICKS     104
++#define TEX_NODE_MATH       105
++#define TEX_NODE_MIX_RGB    106
++#define TEX_NODE_RGBTOBW    107
++#define TEX_NODE_VALTORGB   108
++#define TEX_NODE_IMAGE      109
++#define TEX_NODE_CURVE_RGB  110
++#define TEX_NODE_INVERT     111
++#define TEX_NODE_HUE_SAT    112
++#define TEX_NODE_CURVE_TIME 113
++#define TEX_NODE_ROTATE     114
++#define TEX_NODE_VIEWER     115
++#define TEX_NODE_TRANSLATE  116
++
++/* 201-299 reserved. Use like this: TEX_NODE_PROC + TEX_CLOUDS, etc */
++#define TEX_NODE_PROC      200
++#define TEX_NODE_PROC_MAX  300
++
++extern struct ListBase node_all_textures;
++
++/* API */
++int  ntreeTexTagAnimated(struct bNodeTree *ntree);
++void ntreeTexUpdatePreviews( struct bNodeTree* nodetree );
++void ntreeTexExecTree(struct bNodeTree *ntree, struct TexResult *target, float *coord, char do_preview, short thread, struct Tex *tex, short which_output);
++void ntreeTexCheckCyclics(struct bNodeTree *ntree);
++void ntreeTexAssignIndex(struct bNodeTree *ntree, struct bNode *node);
++char* ntreeTexOutputMenu(struct bNodeTree *ntree);
++
++
++/**/
++
  void init_nodesystem(void);
  void free_nodesystem(void);
  
index 3acc10e8022e6e0ecf126dba9c4fbe0767c08cd5,3d1b342bf732d88f942d0aa50abdac1e1cd9611a..8e36ea0204ba29097f791c89fd836c21a31a93cb
@@@ -613,6 -597,6 +613,8 @@@ static void get_flags_for_id(ID *id, ch
  
        if(GS(id->name)==ID_MA)
                isnode= ((Material *)id)->use_nodes;
++      if(GS(id->name)==ID_TE)
++              isnode= ((Tex *)id)->use_nodes;
        
        if (id->us<0)
                sprintf(buf, "-1W ");
index 95534deae66b425df4c5b86c69c3dd1d88a36df7,27f4fd3bc051110fa1458dbb6631a937cdd8aff3..d697ef2de4e563b434784ffef87ae0c2370b2c8b
@@@ -649,7 -650,7 +649,7 @@@ static void do_init_render_material(Mat
                if(ma->septex & (1<<a)) continue;
  
                mtex= ma->mtex[a];
--              if(mtex && mtex->tex && mtex->tex->type) {
++              if(mtex && mtex->tex && (mtex->tex->type | (mtex->tex->use_nodes && mtex->tex->nodetree) )) {
                        
                        ma->texco |= mtex->texco;
                        ma->mapto |= mtex->mapto;
index 8d60b1b4359c703c664544409c508aa65ee4de78,b881b681ed9872cc1bb34cddcb7e6ee25c6f8cb6..e189891d8840949faf9eeed9fafe92c3c44ecf87
@@@ -38,6 -38,6 +38,7 @@@
  #include "DNA_image_types.h"
  #include "DNA_node_types.h"
  #include "DNA_material_types.h"
++#include "DNA_texture_types.h"
  #include "DNA_text_types.h"
  #include "DNA_scene_types.h"
  
@@@ -70,6 -70,6 +71,8 @@@
  #include "intern/CMP_util.h"  /* stupid include path... */
  
  #include "SHD_node.h"
++#include "TEX_node.h"
++#include "intern/TEX_util.h"
  
  #include "GPU_extensions.h"
  #include "GPU_material.h"
@@@ -77,6 -77,6 +80,7 @@@
  static ListBase empty_list = {NULL, NULL};
  ListBase node_all_composit = {NULL, NULL};
  ListBase node_all_shaders = {NULL, NULL};
++ListBase node_all_textures = {NULL, NULL};
  
  /* ************** Type stuff **********  */
  
@@@ -106,6 -106,6 +110,8 @@@ void ntreeInitTypes(bNodeTree *ntree
                ntree->alltypes= node_all_shaders;
        else if(ntree->type==NTREE_COMPOSIT)
                ntree->alltypes= node_all_composit;
++      else if(ntree->type==NTREE_TEXTURE)
++              ntree->alltypes= node_all_textures;
        else {
                ntree->alltypes= empty_list;
                printf("Error: no type definitions for nodes\n");
@@@ -661,6 -661,6 +667,28 @@@ void nodeVerifyGroup(bNodeTree *ngroup
                        }
                }
        }
++      else if(ngroup->type==NTREE_TEXTURE) {
++              Tex *tx;
++              for(tx= G.main->tex.first; tx; tx= tx->id.next) {
++                      if(tx->nodetree) {
++                              bNode *node;
++                              
++                              /* find if group is in tree */
++                              for(node= tx->nodetree->nodes.first; node; node= node->next)
++                                      if(node->id == (ID *)ngroup)
++                                              break;
++                              
++                              if(node) {
++                                      /* set all type pointers OK */
++                                      ntreeInitTypes(tx->nodetree);
++                                      
++                                      for(node= tx->nodetree->nodes.first; node; node= node->next)
++                                              if(node->id == (ID *)ngroup)
++                                                      nodeVerifyType(tx->nodetree, node);
++                              }
++                      }
++              }
++      }
  }
  
  /* also to check all users of groups. Now only used in editor for hide/unhide */
@@@ -717,6 -717,6 +745,26 @@@ void nodeGroupSocketUseFlags(bNodeTree 
                        }
                }
        }
++      else if(ngroup->type==NTREE_TEXTURE) {
++              Tex *tx;
++              for(tx= G.main->tex.first; tx; tx= tx->id.next) {
++                      if(tx->nodetree) {
++                              for(node= tx->nodetree->nodes.first; node; node= node->next) {
++                                      if(node->id==(ID *)ngroup) {
++                                              for(sock= node->inputs.first; sock; sock= sock->next)
++                                                      if(sock->link)
++                                                              if(sock->tosock) 
++                                                                      sock->tosock->flag |= SOCK_IN_USE;
++                                              for(sock= node->outputs.first; sock; sock= sock->next)
++                                                      if(nodeCountSocketLinks(tx->nodetree, sock))
++                                                              if(sock->tosock) 
++                                                                      sock->tosock->flag |= SOCK_IN_USE;
++                                      }
++                              }
++                      }
++              }
++      }
++      
  }
  
  /* finds a node based on given socket */
@@@ -901,9 -901,9 +949,12 @@@ bNode *nodeAddNodeType(bNodeTree *ntree
        /* got it-bob*/
        if(ntype->initfunc!=NULL)
                ntype->initfunc(node);
++      
++      if(type==TEX_NODE_OUTPUT)
++              ntreeTexAssignIndex(ntree, node);
  
        nodeAddSockets(node, ntype);
--
++      
        return node;
  }
  
@@@ -970,6 -970,6 +1021,9 @@@ bNode *nodeCopyNode(struct bNodeTree *n
        node->new_node= nnode;
        nnode->new_node= NULL;
        nnode->preview= NULL;
++      
++      if(node->type==TEX_NODE_OUTPUT)
++              ntreeTexAssignIndex(ntree, node);
  
        return nnode;
  }
@@@ -1260,6 -1260,6 +1314,22 @@@ void ntreeMakeLocal(bNodeTree *ntree
                        }
                }
        }
++      else if(ntree->type==NTREE_TEXTURE) {
++              Tex *tx;
++              for(tx= G.main->tex.first; tx; tx= tx->id.next) {
++                      if(tx->nodetree) {
++                              bNode *node;
++                              
++                              /* find if group is in tree */
++                              for(node= tx->nodetree->nodes.first; node; node= node->next) {
++                                      if(node->id == (ID *)ntree) {
++                                              if(tx->id.lib) lib= 1;
++                                              else local= 1;
++                                      }
++                              }
++                      }
++              }
++      }
        
        /* if all users are local, we simply make tree local */
        if(local && lib==0) {
                                }
                        }
                }
++              else if(ntree->type==NTREE_TEXTURE) {
++                      Tex *tx;
++                      for(tx= G.main->tex.first; tx; tx= tx->id.next) {
++                              if(tx->nodetree) {
++                                      bNode *node;
++                                      
++                                      /* find if group is in tree */
++                                      for(node= tx->nodetree->nodes.first; node; node= node->next) {
++                                              if(node->id == (ID *)ntree) {
++                                                      if(tx->id.lib==NULL) {
++                                                              node->id= &newtree->id;
++                                                              newtree->id.us++;
++                                                              ntree->id.us--;
++                                                      }
++                                              }
++                                      }
++                              }
++                      }
++              }
        }
  }
  
@@@ -1575,6 -1575,6 +1664,8 @@@ void NodeTagChanged(bNodeTree *ntree, b
                }
                node->need_exec= 1;
        }
++      else if(ntree->type == NTREE_TEXTURE)
++              ntreeTexUpdatePreviews(ntree);
  }
  
  void NodeTagIDChanged(bNodeTree *ntree, ID *id)
@@@ -1813,7 -1813,7 +1904,7 @@@ static void composit_begin_exec(bNodeTr
                                        sock->ns.data= NULL;
                                }
                        }
--              }               
++              }
                /* cannot initialize them while using in threads */
                if(ELEM3(node->type, CMP_NODE_TIME, CMP_NODE_CURVE_VEC, CMP_NODE_CURVE_RGB)) {
                        curvemapping_initialize(node->storage);
@@@ -1929,12 -1929,12 +2020,28 @@@ static void ntreeReleaseThreadStack(bNo
        nts->used= 0;
  }
  
++/* free texture delegates */
++static void tex_end_exec(bNodeTree *ntree)
++{
++      bNodeThreadStack *nts;
++      bNodeStack *ns;
++      int th, a;
++      
++      if(ntree->threadstack)
++              for(th=0; th<BLENDER_MAX_THREADS; th++)
++                      for(nts=ntree->threadstack[th].first; nts; nts=nts->next)
++                              for(ns= nts->stack, a=0; a<ntree->stacksize; a++, ns++)
++                                      if(ns->data)
++                                              MEM_freeN(ns->data);
++                                              
++}
++
  void ntreeBeginExecTree(bNodeTree *ntree)
  {
        /* let's make it sure */
        if(ntree->init & NTREE_EXEC_INIT)
                return;
--
++      
        /* allocate the thread stack listbase array */
        if(ntree->type!=NTREE_COMPOSIT)
                ntree->threadstack= MEM_callocN(BLENDER_MAX_THREADS*sizeof(ListBase), "thread stack array");
@@@ -1986,6 -1986,6 +2093,8 @@@ void ntreeEndExecTree(bNodeTree *ntree
                /* another callback candidate! */
                if(ntree->type==NTREE_COMPOSIT)
                        composit_end_exec(ntree, 0);
++              else if(ntree->type==NTREE_TEXTURE)
++                      tex_end_exec(ntree);
                
                if(ntree->stack) {
                        MEM_freeN(ntree->stack);
@@@ -2622,6 -2622,6 +2731,27 @@@ void ntreeCompositTagGenerators(bNodeTr
        }
  }
  
++int ntreeTexTagAnimated(bNodeTree *ntree)
++{
++      bNode *node;
++      
++      if(ntree==NULL) return 0;
++      
++      for(node= ntree->nodes.first; node; node= node->next) {
++              if(node->type==TEX_NODE_CURVE_TIME) {
++                      NodeTagChanged(ntree, node);
++                      return 1;
++              }
++              else if(node->type==NODE_GROUP) {
++                      if( ntreeTexTagAnimated((bNodeTree *)node->id) ) {
++                              return 1;
++                      }
++              }
++      }
++      
++      return 0;
++}
++
  /* ************* node definition init ********** */
  
  static bNodeType *is_nodetype_registered(ListBase *typelist, int type, ID *id) 
@@@ -2745,6 -2745,6 +2875,41 @@@ static void registerShaderNodes(ListBas
        nodeRegisterType(ntypelist, &sh_node_hue_sat);
  }
  
++static void registerTextureNodes(ListBase *ntypelist)
++{
++      nodeRegisterType(ntypelist, &node_group_typeinfo);
++      nodeRegisterType(ntypelist, &tex_node_math);
++      nodeRegisterType(ntypelist, &tex_node_mix_rgb);
++      nodeRegisterType(ntypelist, &tex_node_valtorgb);
++      nodeRegisterType(ntypelist, &tex_node_rgbtobw);
++      nodeRegisterType(ntypelist, &tex_node_curve_rgb);
++      nodeRegisterType(ntypelist, &tex_node_curve_time);
++      nodeRegisterType(ntypelist, &tex_node_invert);
++      nodeRegisterType(ntypelist, &tex_node_hue_sat);
++      
++      nodeRegisterType(ntypelist, &tex_node_output);
++      nodeRegisterType(ntypelist, &tex_node_viewer);
++      
++      nodeRegisterType(ntypelist, &tex_node_checker);
++      nodeRegisterType(ntypelist, &tex_node_texture);
++      nodeRegisterType(ntypelist, &tex_node_bricks);
++      nodeRegisterType(ntypelist, &tex_node_image);
++      
++      nodeRegisterType(ntypelist, &tex_node_rotate);
++      nodeRegisterType(ntypelist, &tex_node_translate);
++      
++      nodeRegisterType(ntypelist, &tex_node_proc_voronoi);
++      nodeRegisterType(ntypelist, &tex_node_proc_blend);
++      nodeRegisterType(ntypelist, &tex_node_proc_magic);
++      nodeRegisterType(ntypelist, &tex_node_proc_marble);
++      nodeRegisterType(ntypelist, &tex_node_proc_clouds);
++      nodeRegisterType(ntypelist, &tex_node_proc_wood);
++      nodeRegisterType(ntypelist, &tex_node_proc_musgrave);
++      nodeRegisterType(ntypelist, &tex_node_proc_noise);
++      nodeRegisterType(ntypelist, &tex_node_proc_stucci);
++      nodeRegisterType(ntypelist, &tex_node_proc_distnoise);
++}
++
  static void remove_dynamic_typeinfos(ListBase *list)
  {
        bNodeType *ntype= list->first;
@@@ -2782,6 -2782,6 +2947,7 @@@ void init_nodesystem(void
  {
        registerCompositNodes(&node_all_composit);
        registerShaderNodes(&node_all_shaders);
++      registerTextureNodes(&node_all_textures);
  }
  
  void free_nodesystem(void) 
        BLI_freelistN(&node_all_composit);
        remove_dynamic_typeinfos(&node_all_shaders);
        BLI_freelistN(&node_all_shaders);
++      BLI_freelistN(&node_all_textures);
  }
index 372c51b0da5697e26cdd2ccffb93037f2e1bfcbd,ab9e6f9af415c33d5569a459b9369a6eb16c4986..9300b39a7678255dc74a6d3686749bf1ae8f0038
@@@ -420,6 -421,6 +420,11 @@@ void free_texture(Tex *tex
        BKE_previewimg_free(&tex->preview);
        BKE_icon_delete((struct ID*)tex);
        tex->id.icon_id = 0;
++      
++      if(tex->nodetree) {
++              ntreeFreeTree(tex->nodetree);
++              MEM_freeN(tex->nodetree);
++      }
  }
  
  /* ------------------------------------------------------------------------- */
@@@ -577,6 -578,6 +582,11 @@@ Tex *copy_texture(Tex *tex
        
        if(tex->preview) texn->preview = BKE_previewimg_copy(tex->preview);
  
++      if(tex->nodetree) {
++              ntreeEndExecTree(tex->nodetree);
++              texn->nodetree= ntreeCopyTree(tex->nodetree, 0); /* 0 == full new tree */
++      }
++      
        return texn;
  }
  
@@@ -727,6 -728,6 +737,10 @@@ void autotexname(Tex *tex
        char di[FILE_MAXDIR], fi[FILE_MAXFILE];
        
        if(tex) {
++              if(tex->use_nodes) {
++                      new_id(&G.main->tex, (ID *)tex, "Noddy");
++              }
++              else
                if(tex->type==TEX_IMAGE) {
                        ima= tex->ima;
                        if(ima) {
index 1ecd402bd568ea3181737df17135b8090d76060a,acedf51e6191f050d02e7e8c67f3d8bd12766661..ed53c31dd67facca32c1604ecca88a07ebb60eb9
@@@ -1510,6 -1524,6 +1510,7 @@@ static void lib_verify_nodetree(Main *m
  {
        Scene *sce;
        Material *ma;
++      Tex *tx;
        bNodeTree *ntree;
  
        /* this crashes blender on undo/redo
                if(sce->nodetree)
                        ntreeVerifyTypes(sce->nodetree);
        }
++      /* and texture trees */
++      for(tx= main->tex.first; tx; tx= tx->id.next) {
++              if(tx->nodetree)
++                      ntreeVerifyTypes(tx->nodetree);
++      }
  }
  
  
@@@ -1570,6 -1584,6 +1576,9 @@@ static void direct_link_nodetree(FileDa
                                else if(ELEM3(node->type, CMP_NODE_IMAGE, CMP_NODE_VIEWER, CMP_NODE_SPLITVIEWER))
                                        ((ImageUser *)node->storage)->ok= 1;
                        }
++                      else if( ntree->type==NTREE_TEXTURE && (node->type==TEX_NODE_CURVE_RGB || node->type==TEX_NODE_CURVE_TIME) ) {
++                              direct_link_curvemapping(fd, node->storage);
++                      }
                }
                link_list(fd, &node->inputs);
                link_list(fd, &node->outputs);
@@@ -2476,6 -2490,6 +2485,9 @@@ static void lib_link_texture(FileData *
                        tex->ipo= newlibadr_us(fd, tex->id.lib, tex->ipo);
                        if(tex->env) tex->env->object= newlibadr(fd, tex->id.lib, tex->env->object);
  
++                      if(tex->nodetree)
++                              lib_link_ntree(fd, &tex->id, tex->nodetree);
++                      
                        tex->id.flag -= LIB_NEEDLINK;
                }
                tex= tex->id.next;
@@@ -2501,6 -2515,6 +2513,11 @@@ static void direct_link_texture(FileDat
                memset(tex->env->cube, 0, 6*sizeof(void *));
                tex->env->ok= 0;
        }
++      
++      tex->nodetree= newdataadr(fd, tex->nodetree);
++      if(tex->nodetree)
++              direct_link_nodetree(fd, tex->nodetree);
++      
        tex->preview = direct_link_preview_image(fd, tex->preview);
  
        tex->iuser.ok= 1;
@@@ -8395,11 -8306,11 +8412,23 @@@ static void expand_key(FileData *fd, Ma
        expand_doit(fd, mainvar, key->ipo);
  }
  
++static void expand_nodetree(FileData *fd, Main *mainvar, bNodeTree *ntree)
++{
++      bNode *node;
++      
++      for(node= ntree->nodes.first; node; node= node->next)
++              if(node->id && node->type!=CMP_NODE_R_LAYERS)
++                      expand_doit(fd, mainvar, node->id);
++
++}
  
  static void expand_texture(FileData *fd, Main *mainvar, Tex *tex)
  {
        expand_doit(fd, mainvar, tex->ima);
        expand_doit(fd, mainvar, tex->ipo);
++      
++      if(tex->nodetree)
++              expand_nodetree(fd, mainvar, tex->nodetree);
  }
  
  static void expand_brush(FileData *fd, Main *mainvar, Brush *brush)
        expand_doit(fd, mainvar, brush->clone.image);
  }
  
--static void expand_nodetree(FileData *fd, Main *mainvar, bNodeTree *ntree)
--{
--      bNode *node;
--      
--      for(node= ntree->nodes.first; node; node= node->next)
--              if(node->id && node->type!=CMP_NODE_R_LAYERS)
--                      expand_doit(fd, mainvar, node->id);
--
--}
--
  static void expand_material(FileData *fd, Main *mainvar, Material *ma)
  {
        int a;
index a4883087cfa06028c6340357c492a556e7e86041,e9d9fae0936eb80574348d013fa11958771609d3..d84211411fa90030950143e5633087333f823d0c
@@@ -457,6 -470,6 +457,8 @@@ static void write_nodetree(WriteData *w
                                write_curvemapping(wd, node->storage);
                        else if(ntree->type==NTREE_COMPOSIT && (node->type==CMP_NODE_TIME || node->type==CMP_NODE_CURVE_VEC || node->type==CMP_NODE_CURVE_RGB))
                                write_curvemapping(wd, node->storage);
++                      else if(ntree->type==NTREE_TEXTURE && (node->type==TEX_NODE_CURVE_RGB || node->type==TEX_NODE_CURVE_TIME) )
++                              write_curvemapping(wd, node->storage);
                        else 
                                writestruct(wd, DATA, node->typeinfo->storagename, 1, node->storage);
                }
@@@ -1321,6 -1334,6 +1323,12 @@@ static void write_textures(WriteData *w
                        if(tex->coba) writestruct(wd, DATA, "ColorBand", 1, tex->coba);
                        if(tex->env) writestruct(wd, DATA, "EnvMap", 1, tex->env);
                        
++                      /* nodetree is integral part of texture, no libdata */
++                      if(tex->nodetree) {
++                              writestruct(wd, DATA, "bNodeTree", 1, tex->nodetree);
++                              write_nodetree(wd, tex->nodetree);
++                      }
++                      
                        write_previews(wd, tex->preview);
                }
                tex= tex->id.next;
index eda37d952c111198ea82994845d3cdca135f5dc0,eda37d952c111198ea82994845d3cdca135f5dc0..d5eb4024dcc8ee26b782f2c22c47307a8ec71d1a
@@@ -121,6 -121,6 +121,7 @@@ typedef struct bNode 
        float locx, locy;               /* root offset for drawing */
        float width, miniwidth;                 
        short custom1, custom2; /* to be abused for buttons */
++      float custom3, custom4;
        
        short need_exec, exec;  /* need_exec is set as UI execution event, exec is flag during exec */
        
@@@ -156,7 -156,7 +157,7 @@@ typedef struct bNodeLink 
  } bNodeLink;
  
  /* the basis for a Node tree, all links and nodes reside internal here */
--/* only re-usable node trees are in the library though, materials allocate own tree struct */
++/* only re-usable node trees are in the library though, materials and textures allocate own tree struct */
  typedef struct bNodeTree {
        ID id;
        
  /* ntree->type, index */
  #define NTREE_SHADER  0
  #define NTREE_COMPOSIT        1
++#define NTREE_TEXTURE   2
  
  /* ntree->init, flag */
  #define NTREE_TYPE_INIT       1
@@@ -285,4 -285,4 +287,9 @@@ typedef struct NodeLensDist 
        short jit, proj, fit, pad;
  } NodeLensDist;
  
++/* TEX_output */
++typedef struct TexNodeOutput {
++      char name[32];
++} TexNodeOutput;
++
  #endif
index 111dc08ee02dafe9eded41146af798b96338343a,111dc08ee02dafe9eded41146af798b96338343a..6e07336a4b153ae32c752103a7666a78b445f513
@@@ -55,13 -55,13 +55,13 @@@ typedef struct MTex 
        float ofs[3], size[3];
        
        short texflag, colormodel, pmapto, pmaptoneg;
--      short normapspace, pad[3];
++      short normapspace, which_output, pad[2];
        float r, g, b, k;
        float def_var, rt;
        
        float colfac, norfac, varfac;
        float dispfac; 
--      float warpfac; 
++      float warpfac;
        
  } MTex;
  
@@@ -166,6 -166,6 +166,7 @@@ typedef struct Tex 
        
        struct ImageUser iuser;
        
++      struct bNodeTree *nodetree;
        struct Ipo *ipo;
        struct Image *ima;
        struct PluginTex *plugin;
        struct EnvMap *env;
        struct PreviewImage * preview;
        
++      char use_nodes;
++      char pad[7];
++      
  } Tex;
  
  /* used for mapping node. note: rot is in degrees */
index 57f57ebebfea0cf806223e988275c5ad7cb406b6,ee0c82fad623c8c8359ac4d2180503b3f0e42dbb..400064f24b852b4798ea65af369da91441d95353
@@@ -29,6 -29,6 +29,6 @@@
  # Bounces make to subdirectories.
  
  SOURCEDIR = source/blender/nodes
- DIRS = intern
 -DIRS = intern intern/CMP_nodes intern/SHD_nodes
++DIRS = intern intern/CMP_nodes intern/SHD_nodes intern/TEX_nodes
  
  include nan_subdirs.mk
index 5f7f29dab8382bc82a2c948659105da252d2f38a,0cfef20dae78e453783c59a9c50242c694fb6050..5104bcd0046ac3c7094328403ae69fc9004ed91d
@@@ -4,9 -4,9 +4,10 @@@ Import ('env'
  sources = env.Glob('intern/*.c')
  sources += env.Glob('intern/CMP_nodes/*.c')
  sources += env.Glob('intern/SHD_nodes/*.c')
++sources += env.Glob('intern/TEX_nodes/*.c')
  
  incs = '. ./intern '
 -incs += '#/intern/guardedalloc ../include ../blenlib ../makesdna'
 +incs += '#/intern/guardedalloc ../editors/include ../blenlib ../makesdna'
  incs += ' ../render/extern/include '
  incs += ' ../imbuf ../avi '
  incs += ' ../blenloader'
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..6be2123b96d09b4da9fce6c04f710c011220b739
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,70 @@@
++/**
++ * $Id: CMP_node.h 12429 2007-10-29 14:37:19Z bebraw $
++ *
++ * ***** 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. The Blender
++ * Foundation also sells licenses for use in proprietary software under
++ * the Blender License.  See http://www.blender.org/BL/ for information
++ * about this.
++ *
++ * 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): none yet.
++ *
++ * ***** END GPL LICENSE BLOCK *****
++ */
++
++#ifndef TEX_NODE_H
++#define TEX_NODE_H
++
++#include "BKE_node.h"
++
++
++/* ****************** types array for all texture nodes ****************** */
++
++extern bNodeType tex_node_math;
++extern bNodeType tex_node_mix_rgb;
++extern bNodeType tex_node_valtorgb;
++extern bNodeType tex_node_rgbtobw;
++extern bNodeType tex_node_output;
++extern bNodeType tex_node_viewer;
++extern bNodeType tex_node_checker;
++extern bNodeType tex_node_texture;
++extern bNodeType tex_node_bricks;
++extern bNodeType tex_node_image;
++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_rotate;
++extern bNodeType tex_node_translate;
++
++extern bNodeType tex_node_proc_voronoi;
++extern bNodeType tex_node_proc_blend;
++extern bNodeType tex_node_proc_magic;
++extern bNodeType tex_node_proc_marble;
++extern bNodeType tex_node_proc_clouds;
++extern bNodeType tex_node_proc_wood;
++extern bNodeType tex_node_proc_musgrave;
++extern bNodeType tex_node_proc_noise;
++extern bNodeType tex_node_proc_stucci;
++extern bNodeType tex_node_proc_distnoise;
++
++#endif
index 31dbde940fd5eb637bf6aa2b6a45049fca3ff3ab,31dbde940fd5eb637bf6aa2b6a45049fca3ff3ab..908cbf5abfdc179f1994f5b0fc2bad81ace90153
@@@ -50,6 -50,6 +50,9 @@@ static void node_shader_exec_texture(vo
                TexResult texres;
                float vec[3], nor[3]={0.0f, 0.0f, 0.0f};
                int retval;
++              short which_output = node->custom1;
++              
++              short thread = shi->thread;
                
                /* out: value, color, normal */
                
@@@ -61,7 -61,7 +64,7 @@@
                        
                        if(in[0]->datatype==NS_OSA_VECTORS) {
                                float *fp= in[0]->data;
--                              retval= multitex_ext((Tex *)node->id, vec, fp, fp+3, shi->osatex, &texres);
++                              retval= multitex_thread((Tex *)node->id, vec, fp, fp+3, shi->osatex, &texres, thread, which_output);
                        }
                        else if(in[0]->datatype==NS_OSA_VALUES) {
                                float *fp= in[0]->data;
                                
                                dxt[0]= fp[0]; dxt[1]= dxt[2]= 0.0f;
                                dyt[0]= fp[1]; dyt[1]= dyt[2]= 0.0f;
--                              retval= multitex_ext((Tex *)node->id, vec, dxt, dyt, shi->osatex, &texres);
++                              retval= multitex_thread((Tex *)node->id, vec, dxt, dyt, shi->osatex, &texres, thread, which_output);
                        }
                        else
--                              retval= multitex_ext((Tex *)node->id, vec, NULL, NULL, 0, &texres);
++                              retval= multitex_thread((Tex *)node->id, vec, NULL, NULL, 0, &texres, thread, which_output);
                }
--              else {  /* only for previewrender, so we see stuff */
++              else {
                        VECCOPY(vec, shi->lo);
--                      retval= multitex_ext((Tex *)node->id, vec, NULL, NULL, 0, &texres);
++                      retval= multitex_thread((Tex *)node->id, vec, NULL, NULL, 0, &texres, thread, which_output);
                }
                
                /* stupid exception */
index f673834d2b77280fa83bc34f89660aa8b08d417a,f673834d2b77280fa83bc34f89660aa8b08d417a..b5e82db8a933ea8a68bc9dc0ebcafb585a287c36
@@@ -82,6 -82,6 +82,7 @@@ void ntreeShaderExecTree(bNodeTree *ntr
        /* convert caller data to struct */
        scd.shi= shi;
        scd.shr= shr;
++      
        /* each material node has own local shaderesult, with optional copying */
        memset(shr, 0, sizeof(ShadeResult));
                   
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..7fad19a772c22e49afa5ca0a3ff0a800c15e72af
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,48 @@@
++#
++# $Id: Makefile 12796 2007-12-05 16:58:52Z sirdude $
++#
++# ***** BEGIN GPL/BL DUAL 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. The Blender
++# Foundation also sells licenses for use in proprietary software under
++# the Blender License.  See http://www.blender.org/BL/ for information
++# about this.
++#
++# 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) 2001-2002 by NaN Holding BV.
++# All rights reserved.
++#
++# The Original Code is: all of this file.
++#
++# Contributor(s): none yet.
++#
++# ***** END GPL/BL DUAL LICENSE BLOCK *****
++#
++#
++
++LIBNAME = nodes_tex
++DIR = $(OCGDIR)/blender/$(LIBNAME)
++
++include nan_compile.mk
++
++CFLAGS += $(LEVEL_1_C_WARNINGS)
++
++CPPFLAGS += -I../../../blenkernel
++CPPFLAGS += -I$(NAN_GUARDEDALLOC)/include
++CPPFLAGS += -I../../../makesdna
++CPPFLAGS += -I../../../blenlib
++CPPFLAGS += -I../../../include
++CPPFLAGS += -I../../../imbuf
++CPPFLAGS += -I../../../render/extern/include
++CPPFLAGS += -I$(OPENGL_HEADERS)
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..c9fa3528b020dfcc475fd54dfe94c7a200514966
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,123 @@@
++/**
++ *
++ * ***** 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): none yet.
++ *
++ * ***** END GPL LICENSE BLOCK *****
++ */
++
++#include "../TEX_util.h"                                                   
++#include <math.h>
++
++static bNodeSocketType inputs[]= {
++      { SOCK_RGBA,  1, "Bricks 1",    0.596f, 0.282f, 0.0f,  1.0f,  0.0f,    1.0f },
++      { SOCK_RGBA,  1, "Bricks 2",    0.632f, 0.504f, 0.05f, 1.0f,  0.0f,    1.0f },
++      { SOCK_RGBA,  1, "Mortar",      0.0f,   0.0f,   0.0f,  1.0f,  0.0f,    1.0f },
++      { SOCK_VALUE, 1, "Thickness",   0.02f,  0.0f,   0.0f,  0.0f,  0.0f,    1.0f },
++      { SOCK_VALUE, 1, "Bias",        0.0f,   0.0f,   0.0f,  0.0f, -1.0f,    1.0f },
++      { SOCK_VALUE, 1, "Brick Width", 0.5f,   0.0f,   0.0f,  0.0f,  0.001f, 99.0f },
++      { SOCK_VALUE, 1, "Row Height",  0.25f,  0.0f,   0.0f,  0.0f,  0.001f, 99.0f },
++      { -1, 0, "" }
++};
++static bNodeSocketType outputs[]= {
++      { SOCK_RGBA, 0, "Color", 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f},
++      { -1, 0, ""     }
++};
++
++static void init(bNode *node) {
++      node->custom3 = 0.5; /* offset */
++      node->custom4 = 1.0; /* squash */
++}
++
++static void colorfn(float *out, float *coord, bNode *node, bNodeStack **in, short thread)
++{
++      float x = coord[0];
++      float y = coord[1];
++      
++      float bricknum, rownum, offset = 0;
++      float ins_x, ins_y;
++      float tint;
++      
++      float bricks1[4];
++      float bricks2[4];
++      float mortar[4];
++      
++      float mortar_thickness = tex_input_value(in[3], coord, thread);
++      float bias             = tex_input_value(in[4], coord, thread);
++      float brick_width      = tex_input_value(in[5], coord, thread);
++      float row_height       = tex_input_value(in[6], coord, thread);
++      
++      tex_input_rgba(bricks1, in[0], coord, thread);
++      tex_input_rgba(bricks2, in[1], coord, thread);
++      tex_input_rgba(mortar,  in[2], coord, thread);
++      
++      rownum = floor(y / row_height);
++      
++      if( node->custom1 && node->custom2 ) {
++              brick_width *= ((int)(rownum) % node->custom2 ) ? 1.0f : node->custom4;      /* squash */
++              offset = ((int)(rownum) % node->custom1 ) ? 0 : (brick_width*node->custom3); /* offset */
++      }
++      
++      bricknum = floor((x+offset) / brick_width);
++      
++      ins_x = (x+offset) - brick_width*bricknum;
++      ins_y = y - row_height*rownum;
++      
++      srand( (123456*rownum) + bricknum );
++      tint = rand() / (float)RAND_MAX + bias;
++      CLAMP(tint,0.0f,1.0f);
++      
++      if( ins_x < mortar_thickness || ins_y < mortar_thickness ||
++              ins_x > (brick_width - mortar_thickness) ||
++              ins_y > (row_height - mortar_thickness) ) {
++              QUATCOPY( out, mortar );
++      } else {
++              QUATCOPY( out, bricks1 );
++              ramp_blend( MA_RAMP_BLEND, out, out+1, out+2, tint, bricks2 );
++      }
++}
++
++static void exec(void *data, bNode *node, bNodeStack **in, bNodeStack **out)
++{
++      tex_output(node, in, out[0], &colorfn);
++      
++      tex_do_preview(node, out[0], data);
++}
++
++bNodeType tex_node_bricks= {
++      /* *next,*prev */       NULL, NULL,
++      /* type code   */       TEX_NODE_BRICKS,
++      /* name        */       "Bricks",
++      /* width+range */       150, 60, 150,
++      /* class+opts  */       NODE_CLASS_PATTERN, NODE_OPTIONS | NODE_PREVIEW,
++      /* input sock  */       inputs,
++      /* output sock */       outputs,
++      /* storage     */       "", 
++      /* execfunc    */       exec,
++      /* butfunc     */       NULL,
++      /* initfunc    */       init,
++      /* freestoragefunc    */        NULL,
++      /* copystoragefunc    */        NULL,
++      /* id          */       NULL
++      
++};
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..60357782e257c88ca404183d3d164d2baf91542c
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,85 @@@
++/**
++ *
++ * ***** 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): none yet.
++ *
++ * ***** END GPL LICENSE BLOCK *****
++ */
++
++#include "../TEX_util.h"                                                   
++#include <math.h>
++
++static bNodeSocketType inputs[]= {
++      { SOCK_RGBA, 1, "Color1", 1.0f, 0.0f, 0.0f, 1.0f,  0.0f, 1.0f },
++      { SOCK_RGBA, 1, "Color2", 1.0f, 1.0f, 1.0f, 1.0f,  0.0f, 1.0f },
++      { SOCK_VALUE, 1, "Size",   0.5f, 0.0f, 0.0f, 0.0f,  0.0f, 100.0f },
++      { -1, 0, "" }
++};
++static bNodeSocketType outputs[]= {
++      { SOCK_RGBA, 0, "Color", 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f },
++      { -1, 0, "" }
++};
++
++static void colorfn(float *out, float *coord, bNode *node, bNodeStack **in, short thread)
++{
++      float x  = coord[0];
++      float y  = coord[1];
++      float z  = coord[2];
++      float sz = tex_input_value(in[2], coord, thread);
++      
++      /* 0.00001  because of unit sized stuff */
++      int xi = (int)fabs(floor(0.00001 + x / sz));
++      int yi = (int)fabs(floor(0.00001 + y / sz));
++      int zi = (int)fabs(floor(0.00001 + z / sz));
++      
++      if( (xi % 2 == yi % 2) == (zi % 2) ) {
++              tex_input_rgba(out, in[0], coord, thread);
++      } else {
++              tex_input_rgba(out, in[1], coord, thread);
++      } 
++}
++
++static void exec(void *data, bNode *node, bNodeStack **in, bNodeStack **out)
++{
++      tex_output(node, in, out[0], &colorfn);
++      
++      tex_do_preview(node, out[0], data);
++}
++
++bNodeType tex_node_checker= {
++      /* *next,*prev */       NULL, NULL,
++      /* type code   */       TEX_NODE_CHECKER,
++      /* name        */       "Checker",
++      /* width+range */       100, 60, 150,
++      /* class+opts  */       NODE_CLASS_PATTERN, NODE_OPTIONS | NODE_PREVIEW,
++      /* input sock  */       inputs,
++      /* output sock */       outputs,
++      /* storage     */       "", 
++      /* execfunc    */       exec,
++      /* butfunc     */       NULL,
++      /* initfunc    */       NULL,
++      /* freestoragefunc    */        NULL,
++      /* copystoragefunc    */        NULL,
++      /* id          */       NULL
++      
++};
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..8c86656b4f3e32315f7c5e4bbbb7e2916f59a9c0
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,127 @@@
++/**
++ *
++ * ***** 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): none yet.
++ *
++ * ***** END GPL LICENSE BLOCK *****
++ */
++
++#include "../TEX_util.h"
++
++/* **************** CURVE Time  ******************** */
++
++/* custom1 = sfra, custom2 = efra */
++static bNodeSocketType time_outputs[]= {
++      { SOCK_VALUE, 0, "Value",       1.0f, 0.0f, 1.0f, 1.0f, 0.0f, 1.0f },
++      { -1, 0, "" }
++};
++
++static void time_colorfn(float *out, float *coord, bNode *node, bNodeStack **in, short thread)
++{
++      /* stack order output: fac */
++      float fac= 0.0f;
++      
++      if(node->custom1 < node->custom2)
++              fac = (G.scene->r.cfra - node->custom1)/(float)(node->custom2-node->custom1);
++      
++      fac = curvemapping_evaluateF(node->storage, 0, fac);
++      out[0] = CLAMPIS(fac, 0.0f, 1.0f);
++}
++
++static void time_exec(void *data, bNode *node, bNodeStack **in, bNodeStack **out)
++{
++      tex_output(node, in, out[0], &time_colorfn);
++}
++
++
++static void time_init(bNode* node)
++{
++   node->custom1= G.scene->r.sfra;
++   node->custom2= G.scene->r.efra;
++   node->storage= curvemapping_add(1, 0.0f, 0.0f, 1.0f, 1.0f);
++}
++
++bNodeType tex_node_curve_time= {
++      /* *next,*prev */       NULL, NULL,
++      /* type code   */       TEX_NODE_CURVE_TIME,
++      /* name        */       "Time",
++      /* width+range */       140, 100, 320,
++      /* class+opts  */       NODE_CLASS_INPUT, NODE_OPTIONS,
++      /* input sock  */       NULL,
++      /* output sock */       time_outputs,
++      /* storage     */       "CurveMapping",
++      /* execfunc    */       time_exec,
++      /* butfunc     */       NULL,
++      /* initfunc    */       time_init,
++      /* freestoragefunc    */        node_free_curves,
++      /* copystoragefunc    */        node_copy_curves,
++      /* id          */       NULL
++};
++
++/* **************** CURVE RGB  ******************** */
++static bNodeSocketType rgb_inputs[]= {
++      {       SOCK_RGBA, 1, "Color",  0.0f, 0.0f, 0.0f, 1.0f, -1.0f, 1.0f},
++      {       -1, 0, ""       }
++};
++
++static bNodeSocketType rgb_outputs[]= {
++      {       SOCK_RGBA, 0, "Color",  0.0f, 0.0f, 1.0f, 1.0f, -1.0f, 1.0f},
++      {       -1, 0, ""       }
++};
++
++static void rgb_colorfn(float *out, float *coord, bNode *node, bNodeStack **in, short thread)
++{
++      float cin[4];
++      tex_input_rgba(cin, in[0], coord, thread);
++      
++      curvemapping_evaluateRGBF(node->storage, out, cin);
++      out[3] = cin[3];
++}
++
++static void rgb_exec(void *data, bNode *node, bNodeStack **in, bNodeStack **out)
++{
++      tex_output(node, in, out[0], &rgb_colorfn);
++}
++
++static void rgb_init(bNode *node)
++{
++      node->storage= curvemapping_add(4, 0.0f, 0.0f, 1.0f, 1.0f);
++}
++
++bNodeType tex_node_curve_rgb= {
++      /* *next,*prev */    NULL, NULL,
++      /* type code   */    TEX_NODE_CURVE_RGB,
++      /* name        */    "RGB Curves",
++      /* width+range */    200, 140, 320,
++      /* class+opts  */    NODE_CLASS_OP_COLOR, NODE_OPTIONS,
++      /* input sock  */    rgb_inputs,
++      /* output sock */    rgb_outputs,
++      /* storage     */    "CurveMapping",
++      /* execfunc    */    rgb_exec,
++      /* butfunc     */    NULL,      
++      /* initfunc    */     rgb_init,
++      /* freestoragefunc */ node_free_curves,
++      /* copystoragefunc */ node_copy_curves,
++      /* id          */     NULL
++};
++
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..d1a33896fc3f2d74d361174d85bef59ec6f285e8
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,104 @@@
++/**
++ *
++ * ***** 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) 2006 Blender Foundation.
++ * All rights reserved.
++ *
++ * The Original Code is: all of this file.
++ *
++ * Contributor(s): Juho Vepsäläinen
++ *
++ * ***** END GPL LICENSE BLOCK *****
++ */
++
++#include "../TEX_util.h"
++
++
++static bNodeSocketType inputs[]= {
++      {       SOCK_VALUE, 1, "Hue",                   0.5f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
++      {       SOCK_VALUE, 1, "Saturation",            1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 2.0f},
++      {       SOCK_VALUE, 1, "Value",                 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 2.0f},
++      {       SOCK_VALUE, 1, "Fac",                   1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
++      {       SOCK_RGBA, 1, "Color",                  0.8f, 0.8f, 0.8f, 1.0f, 0.0f, 1.0f},
++      {       -1, 0, ""       }
++};
++static bNodeSocketType outputs[]= {
++      {       SOCK_RGBA, 0, "Color",                  0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f},
++      {       -1, 0, ""       }
++};
++
++static void do_hue_sat_fac(bNode *node, float *out, float hue, float sat, float val, float *in, float fac)
++{
++      if(fac != 0 && (hue != 0.5f || sat != 1 || val != 1)) {
++              float col[3], hsv[3], mfac= 1.0f - fac;
++              
++              rgb_to_hsv(in[0], in[1], in[2], hsv, hsv+1, hsv+2);
++              hsv[0]+= (hue - 0.5f);
++              if(hsv[0]>1.0) hsv[0]-=1.0; else if(hsv[0]<0.0) hsv[0]+= 1.0;
++              hsv[1]*= sat;
++              if(hsv[1]>1.0) hsv[1]= 1.0; else if(hsv[1]<0.0) hsv[1]= 0.0;
++              hsv[2]*= val;
++              if(hsv[2]>1.0) hsv[2]= 1.0; else if(hsv[2]<0.0) hsv[2]= 0.0;
++              hsv_to_rgb(hsv[0], hsv[1], hsv[2], col, col+1, col+2);
++              
++              out[0]= mfac*in[0] + fac*col[0];
++              out[1]= mfac*in[1] + fac*col[1];
++              out[2]= mfac*in[2] + fac*col[2];
++      }
++      else {
++              QUATCOPY(out, in);
++      }
++}
++
++static void colorfn(float *out, float *coord, bNode *node, bNodeStack **in, short thread)
++{     
++      float in0 = tex_input_value(in[0], coord, thread);
++      float in1 = tex_input_value(in[1], coord, thread);
++      float in2 = tex_input_value(in[2], coord, thread);
++      float in3 = tex_input_value(in[3], coord, thread);
++      
++      float in4[4];
++      tex_input_rgba(in4, in[4], coord, thread);
++      
++      do_hue_sat_fac(node, out, in0, in1, in2, in4, in3);
++}
++
++static void exec(void *data, bNode *node, bNodeStack **in, bNodeStack **out)
++{
++      tex_output(node, in, out[0], &colorfn);
++}
++
++bNodeType tex_node_hue_sat= {
++      /* *next,*prev */       NULL, NULL,
++      /* type code   */       TEX_NODE_HUE_SAT,
++      /* name        */       "Hue Saturation Value",
++      /* width+range */       150, 80, 250,
++      /* class+opts  */       NODE_CLASS_OP_COLOR, NODE_OPTIONS,
++      /* input sock  */       inputs,
++      /* output sock */       outputs,
++      /* storage     */       "", 
++      /* execfunc    */       exec,
++      /* butfunc     */       NULL,
++      /* initfunc    */       NULL,
++      /* freestoragefunc    */        NULL,
++      /* copystoragefunc    */        NULL,
++      /* id          */       NULL
++      
++};
++
++
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..f9477fef12bf9ff84bae30fae2ce117e4b9cd748
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,106 @@@
++/**
++ * $Id: TEX_image.c 10456 2007-04-04 13:58:12Z jesterking $
++ *
++ * ***** 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) 2006 Blender Foundation.
++ * All rights reserved.
++ *
++ * The Original Code is: all of this file.
++ *
++ * Contributor(s): none yet.
++ *
++ * ***** END GPL LICENSE BLOCK *****
++ */
++
++#include "../TEX_util.h"
++
++static bNodeSocketType outputs[]= {
++      { SOCK_RGBA, 0, "Image",  0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f},
++      { -1, 0, "" }
++};
++
++static void colorfn(float *out, float *coord, bNode *node, bNodeStack **in, short thread)
++{
++      float x = coord[0];
++      float y = coord[1];
++      Image *ima= (Image *)node->id;
++      ImageUser *iuser= (ImageUser *)node->storage;
++      
++      if( ima ) {
++              ImBuf *ibuf = BKE_image_get_ibuf(ima, iuser);
++              if( ibuf ) {
++                      float xsize, ysize;
++                      float xoff, yoff;
++                      int px, py;
++                      
++                      float *result;
++
++                      xsize = ibuf->x / 2;
++                      ysize = ibuf->y / 2;
++                      xoff = yoff = -1;
++                                      
++                      px = (int)( (x-xoff) * xsize );
++                      py = (int)( (y-yoff) * ysize );
++              
++                      if( (!xsize) || (!ysize) ) return;
++                      if( !ibuf->rect_float ) IMB_float_from_rect(ibuf);
++                      
++                      while( px < 0 ) px += ibuf->x;
++                      while( py < 0 ) py += ibuf->y;
++                      while( px >= ibuf->x ) px -= ibuf->x;
++                      while( py >= ibuf->y ) py -= ibuf->y;
++                      
++                      result = ibuf->rect_float + py*ibuf->x*4 + px*4;
++                      QUATCOPY( out, result );
++              }
++      }
++};
++
++static void exec(void *data, bNode *node, bNodeStack **in, bNodeStack **out)
++{
++      tex_output(node, in, out[0], &colorfn);
++      
++      tex_do_preview(node, out[0], data);
++}
++
++static void init(bNode* node)
++{
++   ImageUser *iuser= MEM_callocN(sizeof(ImageUser), "node image user");
++   node->storage= iuser;
++   iuser->sfra= 1;
++   iuser->fie_ima= 2;
++   iuser->ok= 1;
++}
++
++bNodeType tex_node_image= {
++      /* *next,*prev */       NULL, NULL,
++      /* type code   */       TEX_NODE_IMAGE,
++      /* name        */       "Image",
++      /* width+range */       120, 80, 300,
++      /* class+opts  */       NODE_CLASS_INPUT, NODE_PREVIEW|NODE_OPTIONS,
++      /* input sock  */       NULL,
++      /* output sock */       outputs,
++      /* storage     */       "ImageUser",
++      /* execfunc    */       exec,
++      /* butfunc     */       NULL,
++      /* initfunc    */       init,
++      /* freestoragefunc    */        node_free_standard_storage,
++      /* copystoragefunc    */        node_copy_standard_storage,
++      /* id          */       NULL
++};
++
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..09716951009858bacde667a79ae6be5b939a5f9e
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): none yet.
++ *
++ * ***** END GPL LICENSE BLOCK *****
++ */
++
++#include "../TEX_util.h"
++
++/* **************** INVERT ******************** */ 
++static bNodeSocketType inputs[]= { 
++      { SOCK_RGBA, 1, "Color", 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f}, 
++      { -1, 0, "" } 
++};
++
++static bNodeSocketType outputs[]= { 
++      { SOCK_RGBA, 0, "Color", 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f}, 
++      { -1, 0, "" } 
++};
++
++static void colorfn(float *out, float *coord, bNode *node, bNodeStack **in, short thread)
++{
++      float col[4];
++      
++      tex_input_rgba(col, in[0], coord, thread);
++
++      col[0] = 1.0f - col[0];
++      col[1] = 1.0f - col[1];
++      col[2] = 1.0f - col[2];
++      
++      VECCOPY(out, col);
++      out[3] = col[3];
++}
++
++static void exec(void *data, bNode *node, bNodeStack **in, bNodeStack **out)
++{
++      tex_output(node, in, out[0], &colorfn);
++      
++      tex_do_preview(node, out[0], data);
++}
++
++bNodeType tex_node_invert= {
++      /* *next,*prev */       NULL, NULL,
++      /* type code   */       TEX_NODE_INVERT, 
++      /* name        */       "Invert", 
++      /* width+range */       90, 80, 100, 
++      /* class+opts  */       NODE_CLASS_OP_COLOR, NODE_OPTIONS, 
++      /* input sock  */       inputs, 
++      /* output sock */       outputs, 
++      /* storage     */       "", 
++      /* execfunc    */       exec,
++      /* butfunc     */       NULL,
++      /* initfunc    */       NULL,
++      /* freestoragefunc    */        NULL,
++      /* copystoragefunc    */        NULL,
++      /* id          */       NULL
++};
++
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..a2c6607869263845e4d23e1e461ad405214b2d42
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,172 @@@
++/**
++ *
++ * ***** 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): none yet.
++ *
++ * ***** END GPL LICENSE BLOCK *****
++ */
++
++#include "../TEX_util.h"
++
++
++
++/* **************** SCALAR MATH ******************** */ 
++static bNodeSocketType inputs[]= { 
++      { SOCK_VALUE, 1, "Value", 0.5f, 0.5f, 0.5f, 1.0f, -100.0f, 100.0f}, 
++      { SOCK_VALUE, 1, "Value", 0.5f, 0.5f, 0.5f, 1.0f, -100.0f, 100.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 in0 = tex_input_value(in[0], coord, thread);
++      float in1 = tex_input_value(in[1], coord, thread);
++      
++      switch(node->custom1){ 
++      
++      case 0: /* Add */
++              *out= in0 + in1; 
++              break; 
++      case 1: /* Subtract */
++              *out= in0 - in1;
++              break; 
++      case 2: /* Multiply */
++              *out= in0 * in1; 
++              break; 
++      case 3: /* Divide */
++              {
++                      if(in1==0)      /* We don't want to divide by zero. */
++                              *out= 0.0;
++                      else
++                              *out= in0 / in1;
++                      }
++              break;
++      case 4: /* Sine */
++              {
++                      *out= sin(in0);
++              }
++              break;
++      case 5: /* Cosine */
++              {
++                      *out= cos(in0);
++              }
++              break;
++      case 6: /* Tangent */
++              {
++                      *out= tan(in0);
++              }
++              break;
++      case 7: /* Arc-Sine */
++              {
++                      /* Can't do the impossible... */
++                      if( in0 <= 1 && in0 >= -1 )
++                              *out= asin(in0);
++                      else
++                              *out= 0.0;
++              }
++              break;
++      case 8: /* Arc-Cosine */
++              {
++                      /* Can't do the impossible... */
++                      if( in0 <= 1 && in0 >= -1 )
++                              *out= acos(in0);
++                      else
++                              *out= 0.0;
++              }
++              break;
++      case 9: /* Arc-Tangent */
++              {
++                      *out= atan(in0);
++              }
++              break;
++      case 10: /* Power */
++              {
++                      /* Don't want any imaginary numbers... */
++                      if( in0 >= 0 )
++                              *out= pow(in0, in1);
++                      else
++                              *out= 0.0;
++              }
++              break;
++      case 11: /* Logarithm */
++              {
++                      /* Don't want any imaginary numbers... */
++                      if( in0 > 0  && in1 > 0 )
++                              *out= log(in0) / log(in1);
++                      else
++                              *out= 0.0;
++              }
++              break;
++      case 12: /* Minimum */
++              {
++                      if( in0 < in1 )
++                              *out= in0;
++                      else
++                              *out= in1;
++              }
++              break;
++      case 13: /* Maximum */
++              {
++                      if( in0 > in1 )
++                              *out= in0;
++                      else
++                              *out= in1;
++              }
++              break;
++      case 14: /* Round */
++              {
++                      *out= (int)(in0 + 0.5f);
++              }
++              break; 
++      } 
++}
++
++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_math= {
++      /* *next,*prev */       NULL, NULL,
++      /* type code   */       TEX_NODE_MATH, 
++      /* name        */       "Math", 
++      /* width+range */       120, 110, 160, 
++      /* class+opts  */       NODE_CLASS_CONVERTOR, NODE_OPTIONS, 
++      /* input sock  */       inputs, 
++      /* output sock */       outputs, 
++      /* storage     */       "node_math", 
++      /* execfunc    */       exec,
++      /* butfunc     */       NULL,
++      /* initfunc    */       NULL,
++      /* freestoragefunc    */        NULL,
++      /* copystoragefunc    */        NULL,
++      /* id          */       NULL
++};
++
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..b1ccb7a3d07c190c38bfc2bbdeccfc28f387b14a
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,81 @@@
++/**
++ *
++ * ***** 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): none yet.
++ *
++ * ***** END GPL LICENSE BLOCK *****
++ */
++
++#include "../TEX_util.h"
++
++
++/* **************** MIX RGB ******************** */
++static bNodeSocketType inputs[]= {
++      { SOCK_VALUE, 1, "Factor", 0.5f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f },
++      { SOCK_RGBA,  1, "Color1", 0.5f, 0.5f, 0.5f, 1.0f, 0.0f, 1.0f },
++      { SOCK_RGBA , 1, "Color2", 0.5f, 0.5f, 0.5f, 1.0f, 0.0f, 1.0f },
++      { -1, 0, "" }
++};
++static bNodeSocketType outputs[]= {
++      { SOCK_RGBA, 0, "Color", 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f },
++      { -1, 0, "" }
++};
++
++static void colorfn(float *out, float *coord, bNode *node, bNodeStack **in, short thread)
++{
++      float fac  = tex_input_value(in[0], coord, thread);
++      float col1[4], col2[4];
++      
++      tex_input_rgba(col1, in[1], coord, thread);
++      tex_input_rgba(col2, in[2], coord, thread);
++      
++      CLAMP(fac, 0.0f, 1.0f);
++      
++      QUATCOPY(out, col1);
++      ramp_blend(node->custom1, out, out+1, out+2, fac, col2);
++}
++
++static void exec(void *data, bNode *node, bNodeStack **in, bNodeStack **out)
++{
++      tex_output(node, in, out[0], &colorfn);
++      
++      tex_do_preview(node, out[0], data);
++}
++
++bNodeType tex_node_mix_rgb= {
++      /* *next,*prev */       NULL, NULL,
++      /* type code   */       TEX_NODE_MIX_RGB,
++      /* name        */       "Mix",
++      /* width+range */       100, 60, 150,
++      /* class+opts  */       NODE_CLASS_OP_COLOR, NODE_OPTIONS,
++      /* input sock  */       inputs,
++      /* output sock */       outputs,
++      /* storage     */       "", 
++      /* execfunc    */       exec,
++      /* butfunc     */       NULL,
++      /* initfunc    */       NULL,
++      /* freestoragefunc    */        NULL,
++      /* copystoragefunc    */        NULL,
++      /* id          */       NULL
++      
++};
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..060ea8d7e67348b9db3dd663675614e482c98ad9
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,90 @@@
++/**
++ *
++ * ***** 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) 2006 Blender Foundation.
++ * All rights reserved.
++ *
++ * The Original Code is: all of this file.
++ *
++ * Contributor(s): none yet.
++ *
++ * ***** END GPL LICENSE BLOCK *****
++ */
++
++#include "../TEX_util.h"
++
++/* **************** COMPOSITE ******************** */
++static bNodeSocketType inputs[]= {
++      { SOCK_RGBA,   1, "Color",  0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f},
++      { SOCK_VECTOR, 1, "Normal", 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f},
++      { -1, 0, ""     }
++};
++
++/* applies to render pipeline */
++static void exec(void *data, bNode *node, bNodeStack **in, bNodeStack **out)
++{
++      TexCallData *cdata = (TexCallData *)data;
++      TexResult *target = cdata->target;
++      
++      if(in[1]->hasinput && !in[0]->hasinput)
++              tex_do_preview(node, in[1], data);
++      else
++              tex_do_preview(node, in[0], data);
++      
++      if(!cdata->do_preview) {
++              if(cdata->which_output == node->custom1)
++              {
++                      tex_input_rgba(&target->tr, in[0], cdata->coord, cdata->thread);
++              
++                      target->tin = (target->tr + target->tg + target->tb) / 3.0f;
++                      target->talpha = 1.0f;
++              
++                      if(target->nor) {
++                              if(in[1]->hasinput)
++                                      tex_input_vec(target->nor, in[1], cdata->coord, cdata->thread);
++                              else
++                                      target->nor = 0;
++                      }
++              }
++      }
++}
++
++static void init(bNode* node)
++{
++   TexNodeOutput *tno = MEM_callocN(sizeof(TexNodeOutput), "TEX_output");
++   strcpy(tno->name, "Default");
++   node->storage= tno;
++}
++
++
++bNodeType tex_node_output= {
++      /* *next,*prev     */  NULL, NULL,
++      /* type code       */  TEX_NODE_OUTPUT,
++      /* name            */  "Output",
++      /* width+range     */  150, 60, 200,
++      /* class+opts      */  NODE_CLASS_OUTPUT, NODE_PREVIEW | NODE_OPTIONS, 
++      /* input sock      */  inputs,
++      /* output sock     */  NULL,
++      /* storage         */  "TexNodeOutput",
++      /* execfunc        */  exec,
++      /* butfunc         */  NULL,
++      /* initfunc        */  init,
++      /* freestoragefunc */  node_free_standard_storage,
++      /* copystoragefunc */  node_copy_standard_storage,  
++      /* id              */  NULL
++};
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..9078dd1be21ce730f508487d6d4a6ced35ae23db
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,310 @@@
++/**
++ *
++ * ***** 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): none yet.
++ *
++ * ***** END GPL LICENSE BLOCK *****
++ */
++
++#include "../TEX_util.h"
++#include "RE_shader_ext.h"
++
++/* 
++      In this file: wrappers to use procedural textures as nodes
++*/
++
++
++static bNodeSocketType outputs_both[]= {
++      { SOCK_RGBA, 0, "Color",  1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f },
++      { SOCK_VECTOR, 0, "Normal", 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f },
++      { -1, 0, "" }
++};
++static bNodeSocketType outputs_color_only[]= {
++      { SOCK_RGBA, 0, "Color",  1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f },
++      { -1, 0, "" }
++};
++
++/* Inputs common to all, #defined because nodes will need their own inputs too */
++#define I 2 /* count */
++#define COMMON_INPUTS \
++      { SOCK_RGBA, 1, "Color 1", 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f }, \
++      { SOCK_RGBA, 1, "Color 2", 1.0f, 1.0f, 1.0f, 1.0f, 0.0f, 1.0f }
++
++/* Calls multitex and copies the result to the outputs. Called by xxx_exec, which handles inputs. */
++static void do_proc(float *result, float *coord, float *col1, float *col2, char is_normal, Tex *tex, short thread)
++{
++      TexResult texres;
++      int textype;
++      
++      if(is_normal) {
++              texres.nor = result;
++      }
++      else
++              texres.nor = NULL;
++      
++      textype = multitex_thread(tex, coord, 0, 0, 0, &texres, thread, 0);
++      
++      if(is_normal)
++              return;
++      
++      if(textype & TEX_RGB) {
++              QUATCOPY(result, &texres.tr);
++      }
++      else {
++              QUATCOPY(result, col1);
++              ramp_blend(MA_RAMP_BLEND, result, result+1, result+2, texres.tin, col2);
++      }
++}
++
++typedef void (*MapFn) (Tex *tex, bNodeStack **in, float *coord, short thread);
++
++static void texfn(
++      float *result, 
++      float *coord, 
++      bNode *node, 
++      bNodeStack **in,
++      char is_normal, 
++      MapFn map_inputs,
++      short thread)
++{
++      Tex tex = *((Tex*)(node->storage));
++      float col1[4], col2[4];
++      tex_input_rgba(col1, in[0], coord, thread);
++      tex_input_rgba(col2, in[1], coord, thread);
++      
++      map_inputs(&tex, in, coord, thread);
++      
++      do_proc(result, coord, col1, col2, is_normal, &tex, thread);
++}
++
++static int count_outputs(bNode *node)
++{
++      bNodeSocket *sock;
++      int num = 0;
++      for(sock= node->outputs.first; sock; sock= sock->next) {
++              num++;
++      }
++      return num;
++}
++
++/* Boilerplate generators */
++
++#define ProcNoInputs(name) \
++      static void name##_map_inputs(Tex *tex, bNodeStack **in, float *coord, short thread) \
++      {}
++
++#define ProcDef(name) \
++      static void name##_colorfn(float *result, float *coord, bNode *node, bNodeStack **in, short thread)  \
++      {                                                                                                    \
++              texfn(result, coord, node, in, 0, &name##_map_inputs, thread);                               \
++      }                                                                                                    \
++      static void name##_normalfn(float *result, float *coord, bNode *node, bNodeStack **in, short thread) \
++      {                                                                                                    \
++              texfn(result, coord, node, in, 1, &name##_map_inputs, thread);                               \
++      }                                                                                                    \
++      static void name##_exec(void *data, bNode *node, bNodeStack **in, bNodeStack **out)                  \
++      {                                                                                                    \
++              int outs = count_outputs(node);                                                              \
++              if(outs >= 1) tex_output(node, in, out[0], &name##_colorfn);                                 \
++              if(outs >= 2) tex_output(node, in, out[1], &name##_normalfn);                                \
++              if(outs >= 1) tex_do_preview(node, out[0], data);                                            \
++      }
++
++
++/* --- VORONOI -- */
++static bNodeSocketType voronoi_inputs[]= {
++      COMMON_INPUTS,
++      { SOCK_VALUE, 1, "W1", 1.0f, 0.0f, 0.0f, 0.0f,   -2.0f, 2.0f },
++      { SOCK_VALUE, 1, "W2", 0.0f, 0.0f, 0.0f, 0.0f,   -2.0f, 2.0f },
++      { SOCK_VALUE, 1, "W3", 0.0f, 0.0f, 0.0f, 0.0f,   -2.0f, 2.0f },
++      { SOCK_VALUE, 1, "W4", 0.0f, 0.0f, 0.0f, 0.0f,   -2.0f, 2.0f },
++      
++      { SOCK_VALUE, 1, "iScale", 1.0f, 0.0f, 0.0f, 0.0f,    0.01f,  10.0f },
++      { SOCK_VALUE, 1, "Size",   0.25f, 0.0f, 0.0f, 0.0f,   0.0001f, 4.0f },
++      
++      { -1, 0, "" }
++};
++static void voronoi_map_inputs(Tex *tex, bNodeStack **in, float *coord, short thread)
++{
++      tex->vn_w1 = tex_input_value(in[I+0], coord, thread);
++      tex->vn_w2 = tex_input_value(in[I+1], coord, thread);
++      tex->vn_w3 = tex_input_value(in[I+2], coord, thread);
++      tex->vn_w4 = tex_input_value(in[I+3], coord, thread);
++      
++      tex->ns_outscale = tex_input_value(in[I+4], coord, thread);
++      tex->noisesize   = tex_input_value(in[I+5], coord, thread);
++}
++ProcDef(voronoi)
++
++/* --- BLEND -- */
++static bNodeSocketType blend_inputs[]= {
++      COMMON_INPUTS,
++      { -1, 0, "" }
++};
++ProcNoInputs(blend)
++ProcDef(blend)
++
++/* -- MAGIC -- */
++static bNodeSocketType magic_inputs[]= {
++      COMMON_INPUTS,
++      { SOCK_VALUE, 1, "Turbulence", 5.0f, 0.0f, 0.0f, 0.0f,   0.0f, 200.0f },
++      { -1, 0, "" }
++};
++static void magic_map_inputs(Tex *tex, bNodeStack **in, float *coord, short thread)
++{
++      tex->turbul = tex_input_value(in[I+0], coord, thread);
++}
++ProcDef(magic)
++
++/* --- MARBLE --- */
++static bNodeSocketType marble_inputs[]= {
++      COMMON_INPUTS,
++      { SOCK_VALUE, 1, "Size",       0.25f, 0.0f, 0.0f, 0.0f,   0.0001f, 2.0f },
++      { SOCK_VALUE, 1, "Turbulence", 5.0f,  0.0f, 0.0f, 0.0f,   0.0f, 200.0f },
++      { -1, 0, "" }
++};
++static void marble_map_inputs(Tex *tex, bNodeStack **in, float *coord, short thread)
++{
++      tex->noisesize = tex_input_value(in[I+0], coord, thread);
++      tex->turbul    = tex_input_value(in[I+1], coord, thread);
++}
++ProcDef(marble)
++
++/* --- CLOUDS --- */
++static bNodeSocketType clouds_inputs[]= {
++      COMMON_INPUTS,
++      { SOCK_VALUE, 1, "Size",       0.25f, 0.0f, 0.0f, 0.0f,   0.0001f, 2.0f },
++      { -1, 0, "" }
++};
++static void clouds_map_inputs(Tex *tex, bNodeStack **in, float *coord, short thread)
++{
++      tex->noisesize = tex_input_value(in[I+0], coord, thread);
++}
++ProcDef(clouds)
++
++/* --- DISTORTED NOISE --- */
++static bNodeSocketType distnoise_inputs[]= {
++      COMMON_INPUTS,
++      { SOCK_VALUE, 1, "Size",       0.25f, 0.0f, 0.0f, 0.0f,   0.0001f,  2.0f },
++      { SOCK_VALUE, 1, "Distortion", 1.00f, 0.0f, 0.0f, 0.0f,   0.0000f, 10.0f },
++      { -1, 0, "" }
++};
++static void distnoise_map_inputs(Tex *tex, bNodeStack **in, float *coord, short thread)
++{
++      tex->noisesize   = tex_input_value(in[I+0], coord, thread);
++      tex->dist_amount = tex_input_value(in[I+1], coord, thread);
++}
++ProcDef(distnoise)
++
++/* --- WOOD --- */
++static bNodeSocketType wood_inputs[]= {
++      COMMON_INPUTS,
++      { SOCK_VALUE, 1, "Size",       0.25f, 0.0f, 0.0f, 0.0f,   0.0001f, 2.0f },
++      { SOCK_VALUE, 1, "Turbulence", 5.0f,  0.0f, 0.0f, 0.0f,   0.0f, 200.0f },
++      { -1, 0, "" }
++};
++static void wood_map_inputs(Tex *tex, bNodeStack **in, float *coord, short thread)
++{
++      tex->noisesize = tex_input_value(in[I+0], coord, thread);
++      tex->turbul    = tex_input_value(in[I+1], coord, thread);
++}
++ProcDef(wood)
++
++/* --- MUSGRAVE --- */
++static bNodeSocketType musgrave_inputs[]= {
++      COMMON_INPUTS,
++      { SOCK_VALUE, 1, "H",          1.0f, 0.0f, 0.0f, 0.0f,   0.0001f, 2.0f },
++      { SOCK_VALUE, 1, "Lacunarity", 2.0f, 0.0f, 0.0f, 0.0f,   0.0f,    6.0f },
++      { SOCK_VALUE, 1, "Octaves",    2.0f, 0.0f, 0.0f, 0.0f,   0.0f,    8.0f },
++      
++      { SOCK_VALUE, 1, "iScale",     1.0f,  0.0f, 0.0f, 0.0f,  0.0f,   10.0f },
++      { SOCK_VALUE, 1, "Size",       0.25f, 0.0f, 0.0f, 0.0f,  0.0001f, 2.0f },
++      { -1, 0, "" }
++};
++static void musgrave_map_inputs(Tex *tex, bNodeStack **in, float *coord, short thread)
++{
++      tex->mg_H          = tex_input_value(in[I+0], coord, thread);
++      tex->mg_lacunarity = tex_input_value(in[I+1], coord, thread);
++      tex->mg_octaves    = tex_input_value(in[I+2], coord, thread);
++      tex->ns_outscale   = tex_input_value(in[I+3], coord, thread);
++      tex->noisesize     = tex_input_value(in[I+4], coord, thread);
++}
++ProcDef(musgrave)
++
++/* --- NOISE --- */
++static bNodeSocketType noise_inputs[]= {
++      COMMON_INPUTS,
++      { -1, 0, "" }
++};
++ProcNoInputs(noise)
++ProcDef(noise)
++
++/* --- STUCCI --- */
++static bNodeSocketType stucci_inputs[]= {
++      COMMON_INPUTS,
++      { SOCK_VALUE, 1, "Size",       0.25f, 0.0f, 0.0f, 0.0f,   0.0001f, 2.0f },
++      { SOCK_VALUE, 1, "Turbulence", 5.0f,  0.0f, 0.0f, 0.0f,   0.0f, 200.0f },
++      { -1, 0, "" }
++};
++static void stucci_map_inputs(Tex *tex, bNodeStack **in, float *coord, short thread)
++{
++      tex->noisesize = tex_input_value(in[I+0], coord, thread);
++      tex->turbul    = tex_input_value(in[I+1], coord, thread);
++}
++ProcDef(stucci)
++
++/* --- */
++
++static void init(bNode *node)
++{
++      Tex *tex = MEM_callocN(sizeof(Tex), "Tex");
++      node->storage= tex;
++      
++      default_tex(tex);
++      tex->type = node->type - TEX_NODE_PROC;
++      
++      if(tex->type == TEX_WOOD)
++              tex->stype = TEX_BANDNOISE;
++      
++}
++
++/* Node type definitions */
++#define TexDef(TEXTYPE, outputs, name, Name) \
++      { NULL, NULL, TEX_NODE_PROC+TEXTYPE, Name, 140,80,140, NODE_CLASS_TEXTURE, \
++      NODE_OPTIONS | NODE_PREVIEW, name##_inputs, outputs, "Tex", name##_exec, NULL, init, \
++      node_free_standard_storage, node_copy_standard_storage, NULL }
++      
++#define C outputs_color_only
++#define CV outputs_both
++      
++bNodeType tex_node_proc_voronoi   = TexDef(TEX_VORONOI,   CV, voronoi,   "Voronoi"  );
++bNodeType tex_node_proc_blend     = TexDef(TEX_BLEND,     C,  blend,     "Blend"    );
++bNodeType tex_node_proc_magic     = TexDef(TEX_MAGIC,     C,  magic,     "Magic"    );
++bNodeType tex_node_proc_marble    = TexDef(TEX_MARBLE,    CV, marble,    "Marble"   );
++bNodeType tex_node_proc_clouds    = TexDef(TEX_CLOUDS,    CV, clouds,    "Clouds"   );
++bNodeType tex_node_proc_wood      = TexDef(TEX_WOOD,      CV, wood,      "Wood"     );
++bNodeType tex_node_proc_musgrave  = TexDef(TEX_MUSGRAVE,  CV, musgrave,  "Musgrave" );
++bNodeType tex_node_proc_noise     = TexDef(TEX_NOISE,     C,  noise,     "Noise"    );
++bNodeType tex_node_proc_stucci    = TexDef(TEX_STUCCI,    CV, stucci,    "Stucci"   );
++bNodeType tex_node_proc_distnoise = TexDef(TEX_DISTNOISE, CV, distnoise, "Distorted Noise" );
++
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..93bf17d48621d578a8af84d88449a8a54267e833
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,114 @@@
++/**
++ *
++ * ***** 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): none yet.
++ *
++ * ***** END GPL LICENSE BLOCK *****
++ */
++
++#include <math.h>
++#include "MTC_vectorops.h"
++#include "../TEX_util.h"
++
++static bNodeSocketType inputs[]= { 
++      { SOCK_RGBA, 1, "Color", 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f},
++      { SOCK_VALUE, 1, "Turns",   0.0f, 0.0f, 0.0f, 0.0f,  -1.0f, 1.0f },
++      { SOCK_VECTOR, 1, "Axis",   0.0f, 0.0f, 1.0f, 0.0f,  -1.0f, 1.0f },
++      { -1, 0, "" } 
++};
++
++static bNodeSocketType outputs[]= { 
++      { SOCK_RGBA, 0, "Color", 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f}, 
++      { -1, 0, "" } 
++};
++
++static void colorfn(float *out, float *coord, bNode *node, bNodeStack **in, short thread)
++{
++      float new_coord[3];
++      
++      float ax[4];
++      float para[3];
++      float perp[3];
++      float cp[3];
++      
++      float magsq, ndx;
++      
++      float a = tex_input_value(in[1], coord, thread);
++      float cos_a = cos(a * 2 * M_PI);
++      float sin_a = sin(a * 2 * M_PI);
++      
++      // x' = xcosa + n(n.x)(1-cosa)+(x*n)sina
++      
++      tex_input_vec(ax, in[2], coord, thread);
++      magsq = ax[0]*ax[0] + ax[1]*ax[1] + ax[2]*ax[2];
++      
++      if(magsq == 0) magsq = 1;
++      
++      ndx = MTC_dot3Float(coord, ax);
++      
++      para[0] = ax[0] * ndx * (1 - cos_a);
++      para[1] = ax[1] * ndx * (1 - cos_a);
++      para[2] = ax[2] * ndx * (1 - cos_a);
++      
++      MTC_diff3Float(perp, coord, para);
++      
++      perp[0] = coord[0] * cos_a;
++      perp[1] = coord[1] * cos_a;
++      perp[2] = coord[2] * cos_a;
++      
++      MTC_cross3Float(cp, ax, coord);
++      
++      cp[0] = cp[0] * sin_a;
++      cp[1] = cp[1] * sin_a;
++      cp[2] = cp[2] * sin_a;
++      
++      new_coord[0] = para[0] + perp[0] + cp[0];
++      new_coord[1] = para[1] + perp[1] + cp[1];
++      new_coord[2] = para[2] + perp[2] + cp[2];
++      
++      tex_input_rgba(out, in[0], new_coord, thread);
++}
++static void exec(void *data, bNode *node, bNodeStack **in, bNodeStack **out) 
++{
++      tex_output(node, in, out[0], &colorfn);
++      
++      tex_do_preview(node, out[0], data);
++}
++
++bNodeType tex_node_rotate= {
++      /* *next,*prev */       NULL, NULL,
++      /* type code   */       TEX_NODE_ROTATE, 
++      /* name        */       "Rotate", 
++      /* width+range */       90, 80, 100, 
++      /* class+opts  */       NODE_CLASS_DISTORT, NODE_OPTIONS, 
++      /* input sock  */       inputs, 
++      /* output sock */       outputs, 
++      /* storage     */       "", 
++      /* execfunc    */       exec,
++      /* butfunc     */       NULL,
++      /* initfunc    */       NULL,
++      /* freestoragefunc    */        NULL,
++      /* copystoragefunc    */        NULL,
++      /* id          */       NULL
++};
++
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..884d2cd0eb66cb6ed232722b8c18dfda2e803b29
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,103 @@@
++/**
++ *
++ * ***** 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): none yet.
++ *
++ * ***** END GPL LICENSE BLOCK *****
++ */
++
++#include "../TEX_util.h"
++#include "RE_shader_ext.h"
++
++static bNodeSocketType inputs[]= {
++      { SOCK_RGBA, 1, "Color1", 1.0f, 1.0f, 1.0f, 1.0f, 0.0f, 1.0f },
++      { SOCK_RGBA, 1, "Color2", 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f },
++      { -1, 0, "" }
++};
++
++static bNodeSocketType outputs[]= {
++      { SOCK_RGBA, 0, "Color", 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f },
++      { -1, 0, "" }
++};
++
++static void colorfn(float *out, float *coord, bNode *node, bNodeStack **in, short thread)
++{
++      static float red[] = {1,0,0,1};
++      static float white[] = {1,1,1,1};
++      
++      Tex *nodetex = (Tex *)node->id;
++      
++      if(node->custom2) {
++              /* this node refers to its own texture tree! */
++              QUATCOPY(
++                      out,
++                      (fabs(coord[0] - coord[1]) < .01) ? white : red 
++              );
++      }
++      else if(nodetex) {
++              TexResult texres;
++              int textype;
++              float nor[] = {0,0,0};
++              float col1[4], col2[4];
++              
++              tex_input_rgba(col1, in[0], coord, thread);
++              tex_input_rgba(col2, in[1], coord, thread);
++              
++              texres.nor = nor;
++              textype = multitex_ext(nodetex, coord, 0, 0, 0, &texres);
++              
++              if(textype & TEX_RGB) {
++                      QUATCOPY(out, &texres.tr);
++              }
++              else {
++                      QUATCOPY(out, col1);
++                      ramp_blend(MA_RAMP_BLEND, out, out+1, out+2, texres.tin, col2);
++              }
++      }
++}
++
++static void exec(void *data, bNode *node, bNodeStack **in, bNodeStack **out)
++{
++      tex_output(node, in, out[0], &colorfn);
++      
++      tex_do_preview(node, out[0], data);
++}
++
++bNodeType tex_node_texture= {
++      /* *next,*prev */       NULL, NULL,
++      /* type code   */       TEX_NODE_TEXTURE,
++      /* name        */       "Texture",
++      /* width+range */       120, 80, 240,
++      /* class+opts  */       NODE_CLASS_INPUT, NODE_OPTIONS|NODE_PREVIEW,
++      /* input sock  */       inputs,
++      /* output sock */       outputs,
++      /* storage     */       "",
++      /* execfunc    */       exec,
++      /* butfunc     */       NULL,
++      /* initfunc        */   NULL,
++      /* freestoragefunc */   NULL,
++      /* copystoragefunc */   NULL, 
++      /* id          */       NULL
++      
++};
++
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..bd7e61d0ff49b4370e30f5883608650cb790ef07
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,78 @@@
++/**
++ *
++ * ***** 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): none yet.
++ *
++ * ***** END GPL LICENSE BLOCK *****
++ */
++
++#include <math.h>
++#include "../TEX_util.h"
++
++static bNodeSocketType inputs[]= { 
++      { SOCK_RGBA, 1, "Color", 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f},
++      { SOCK_VECTOR, 1, "Offset",   0.0f, 0.0f, 0.0f, 0.0f,  -1.0f, 1.0f },
++      { -1, 0, "" } 
++};
++
++static bNodeSocketType outputs[]= { 
++      { SOCK_RGBA, 0, "Color", 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f}, 
++      { -1, 0, "" } 
++};
++
++static void colorfn(float *out, float *coord, bNode *node, bNodeStack **in, short thread)
++{
++      float offset[3], new_coord[3];
++      
++      tex_input_vec(offset, in[1], coord, thread);
++      
++      new_coord[0] = coord[0] + offset[0];
++      new_coord[1] = coord[1] + offset[1];
++      new_coord[2] = coord[2] + offset[2];
++      
++      tex_input_rgba(out, in[0], new_coord, thread);
++}
++static void exec(void *data, bNode *node, bNodeStack **in, bNodeStack **out) 
++{
++      tex_output(node, in, out[0], &colorfn);
++      
++      tex_do_preview(node, out[0], data);
++}
++
++bNodeType tex_node_translate = {
++      /* *next,*prev */       NULL, NULL,
++      /* type code   */       TEX_NODE_TRANSLATE, 
++      /* name        */       "Translate", 
++      /* width+range */       90, 80, 100, 
++      /* class+opts  */       NODE_CLASS_DISTORT, NODE_OPTIONS, 
++      /* input sock  */       inputs, 
++      /* output sock */       outputs, 
++      /* storage     */       "", 
++      /* execfunc    */       exec,
++      /* butfunc     */       NULL,
++      /* initfunc    */       NULL,
++      /* freestoragefunc    */        NULL,
++      /* copystoragefunc    */        NULL,
++      /* id          */       NULL
++};
++
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..ec59769fdfd9d7bcfc7ed703da6b0ae82eeb6f2b
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,122 @@@
++/**
++ * $Id: SHD_valToRgb.c 10456 2007-04-04 13:58:12Z jesterking $
++ *
++ * ***** 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): none yet.
++ *
++ * ***** END GPL LICENSE BLOCK *****
++ */
++
++#include "../TEX_util.h"
++
++/* **************** VALTORGB ******************** */
++static bNodeSocketType valtorgb_in[]= {
++      {       SOCK_VALUE, 1, "Fac",                   0.5f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
++      {       -1, 0, ""       }
++};
++static bNodeSocketType valtorgb_out[]= {
++      {       SOCK_RGBA, 0, "Color",                  0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f},
++      {       -1, 0, ""       }
++};
++
++static void valtorgb_colorfn(float *out, float *coord, bNode *node, bNodeStack **in, short thread)
++{
++      if(node->storage) {
++              float fac = tex_input_value(in[0], coord, thread);
++
++              do_colorband(node->storage, fac, out);
++      }
++}
++
++static void valtorgb_exec(void *data, bNode *node, bNodeStack **in, bNodeStack **out) 
++{
++      tex_output(node, in, out[0], &valtorgb_colorfn);
++}
++
++static void valtorgb_init(bNode *node)
++{
++      node->storage = add_colorband(1);
++}
++
++bNodeType tex_node_valtorgb= {
++      /* *next,*prev */       NULL, NULL,
++      /* type code   */       TEX_NODE_VALTORGB,
++      /* name        */       "ColorRamp",
++      /* width+range */       240, 200, 300,
++      /* class+opts  */       NODE_CLASS_CONVERTOR, NODE_OPTIONS,
++      /* input sock  */       valtorgb_in,
++      /* output sock */       valtorgb_out,
++      /* storage     */       "ColorBand",
++      /* execfunc    */       valtorgb_exec,
++      /* butfunc     */       NULL,
++      /* initfunc    */       valtorgb_init,
++      /* freestoragefunc    */        node_free_standard_storage,
++      /* copystoragefunc    */        node_copy_standard_storage,
++      /* id          */       NULL
++      
++};
++
++/* **************** RGBTOBW ******************** */
++static bNodeSocketType rgbtobw_in[]= {
++   {  SOCK_RGBA, 1, "Color",                  0.5f, 0.5f, 0.5f, 1.0f, 0.0f, 1.0f},
++   {  -1, 0, ""       }
++};
++static bNodeSocketType rgbtobw_out[]= {
++   {  SOCK_VALUE, 0, "Val",                   0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f},
++   {  -1, 0, ""       }
++};
++
++
++static void rgbtobw_valuefn(float *out, float *coord, bNode *node, bNodeStack **in, short thread)
++{
++      float cin[4];
++      tex_input_rgba(cin, in[0], coord, thread);
++      
++      *out = cin[0] * 0.35f + cin[1] * 0.45f + cin[2] * 0.2f;
++}
++
++static void rgbtobw_exec(void *data, bNode *node, bNodeStack **in, bNodeStack **out)
++{
++      tex_output(node, in, out[0], &rgbtobw_valuefn);
++      
++      tex_do_preview(node, out[0], data);
++}
++
++bNodeType tex_node_rgbtobw= {
++      /* *next,*prev */       NULL, NULL,
++      /* type code   */       TEX_NODE_RGBTOBW,
++      /* name        */       "RGB to BW",
++      /* width+range */       80, 40, 120,
++      /* class+opts  */       NODE_CLASS_CONVERTOR, 0,
++      /* input sock  */       rgbtobw_in,
++      /* output sock */       rgbtobw_out,
++      /* storage     */       "",
++      /* execfunc    */       rgbtobw_exec,
++      /* butfunc     */       NULL,
++      /* initfunc    */       NULL,
++      /* freestoragefunc    */        NULL,
++      /* copystoragefunc    */        NULL,
++      /* id          */       NULL
++
++};
++
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..acdaacf873c76d73f42a87f328ff4df4a639de51
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,61 @@@
++/**
++ *
++ * ***** 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): none yet.
++ *
++ * ***** END GPL LICENSE BLOCK *****
++ */
++
++#include "../TEX_util.h"                                                   
++#include <math.h>
++
++static bNodeSocketType inputs[]= {
++      { SOCK_RGBA, 1, "Color", 1.0f, 0.0f, 0.0f, 1.0f,  0.0f, 1.0f },
++      { -1, 0, "" }
++};
++static bNodeSocketType outputs[]= {
++      { -1, 0, "" }
++};
++
++static void exec(void *data, bNode *node, bNodeStack **in, bNodeStack **out)
++{
++      tex_do_preview(node, in[0], data);
++}
++
++bNodeType tex_node_viewer = {
++      /* *next,*prev */       NULL, NULL,
++      /* type code   */       TEX_NODE_VIEWER,
++      /* name        */       "Viewer",
++      /* width+range */       100, 60, 150,
++      /* class+opts  */       NODE_CLASS_OUTPUT, NODE_PREVIEW,
++      /* input sock  */       inputs,
++      /* output sock */       outputs,
++      /* storage     */       "", 
++      /* execfunc    */       exec,
++      /* butfunc     */       NULL,
++      /* initfunc    */       NULL,
++      /* freestoragefunc    */        NULL,
++      /* copystoragefunc    */        NULL,
++      /* id          */       NULL
++      
++};
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..10fe3bab26c4e30a0cf13e14bcbe25de6c6e59ae
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,270 @@@
++/**
++ *
++ * ***** 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): none yet.
++ *
++ * ***** END GPL LICENSE BLOCK *****
++ */
++ 
++/*
++      HOW TEXTURE NODES WORK
++
++      In contrast to Shader nodes, which place a colour into the output
++      stack when executed, Texture nodes place a TexDelegate* there. To
++      obtain a colour value from this, a node further up the chain reads
++      the TexDelegate* from its input stack, and uses tex_call_delegate to
++      retrieve the colour from the delegate.
++*/
++
++#include <assert.h>
++#include "TEX_util.h"
++
++#define PREV_RES 128 /* default preview resolution */
++
++void tex_call_delegate(TexDelegate *dg, float *out, float *coord, short thread)
++{
++      dg->fn(out, coord, dg->node, dg->in, thread);
++}
++
++void tex_input_vec(float *out, bNodeStack *in, float *coord, short thread)
++{
++      TexDelegate *dg = in->data;
++      if(dg) {
++              tex_call_delegate(dg, out, coord, thread);
++      
++              if(in->hasoutput && in->sockettype == SOCK_VALUE) {
++                      out[1] = out[2] = out[0];
++                      out[3] = 1;
++              }
++      }
++      else {
++              QUATCOPY(out, in->vec);
++      }
++}
++
++void tex_input_rgba(float *out, bNodeStack *in, float *coord, short thread)
++{
++      tex_input_vec(out, in, coord, thread);
++      
++      if(in->hasoutput && in->sockettype == SOCK_VECTOR) {
++              out[0] = out[0] * .5f + .5f;
++              out[1] = out[1] * .5f + .5f;
++              out[2] = out[2] * .5f + .5f;
++              out[3] = 1;
++      }
++}
++
++float tex_input_value(bNodeStack *in, float *coord, short thread)
++{
++      float out[4];
++      tex_input_vec(out, in, coord, thread);
++      return out[0];
++}
++
++static void init_preview(bNode *node)
++{
++      int xsize = node->prvr.xmax - node->prvr.xmin;
++      int ysize = node->prvr.ymax - node->prvr.ymin;
++      
++      if(xsize == 0) {
++              xsize = PREV_RES;
++              ysize = PREV_RES;
++      }
++      
++      if(node->preview==NULL)
++              node->preview= MEM_callocN(sizeof(bNodePreview), "node preview");
++      
++      if(node->preview->rect)
++              if(node->preview->xsize!=xsize && node->preview->ysize!=ysize) {
++                      MEM_freeN(node->preview->rect);
++                      node->preview->rect= NULL;
++              }
++      
++      if(node->preview->rect==NULL) {
++              node->preview->rect= MEM_callocN(4*xsize + xsize*ysize*sizeof(float)*4, "node preview rect");
++              node->preview->xsize= xsize;
++              node->preview->ysize= ysize;
++      }
++}
++
++void tex_do_preview(bNode *node, bNodeStack *ns, TexCallData *cdata)
++{
++      int x, y;
++      float *result;
++      bNodePreview *preview;
++      
++      if(!cdata->do_preview)
++              return;
++      
++      if(!(node->typeinfo->flag & NODE_PREVIEW))
++              return;
++      
++      init_preview(node);
++      
++      preview = node->preview;
++      
++      for(x=0; x<preview->xsize; x++)
++      for(y=0; y<preview->ysize; y++)
++      {
++              cdata->coord[0] = ((float) x / preview->xsize) * 2 - 1;
++              cdata->coord[1] = ((float) y / preview->ysize) * 2 - 1;
++              
++              result = preview->rect + 4 * (preview->xsize*y + x);
++              
++              tex_input_rgba(result, ns, cdata->coord, cdata->thread);
++      }
++}
++
++void tex_output(bNode *node, bNodeStack **in, bNodeStack *out, TexFn texfn)
++{
++      TexDelegate *dg;
++      if(!out->data)
++              /* Freed in tex_end_exec (node.c) */
++              dg = out->data = MEM_mallocN(sizeof(TexDelegate), "tex delegate");
++      else
++              dg = out->data;
++      
++      
++      dg->fn = texfn;
++      dg->node = node;
++      memcpy(dg->in, in, MAX_SOCKET * sizeof(bNodeStack*));
++      dg->type = out->sockettype;
++}
++
++void ntreeTexCheckCyclics(struct bNodeTree *ntree)
++{
++      bNode *node;
++      for(node= ntree->nodes.first; node; node= node->next) {
++              
++              if(node->type == TEX_NODE_TEXTURE && node->id)
++              {
++                      /* custom2 stops the node from rendering */
++                      if(node->custom1) {
++                              node->custom2 = 1;
++                              node->custom1 = 0;
++                      } else {
++                              Tex *tex = (Tex *)node->id;
++                              
++                              node->custom2 = 0;
++                      
++                              node->custom1 = 1;
++                              if(tex->use_nodes && tex->nodetree) {
++                                      ntreeTexCheckCyclics(tex->nodetree);
++                              }
++                              node->custom1 = 0;
++                      }
++              }
++
++      }
++}
++
++void ntreeTexExecTree(bNodeTree *nodes, TexResult *texres, float *coord, char do_preview, short thread, Tex *tex, short which_output)
++{
++      TexResult dummy_texres;
++      TexCallData data;
++      
++      if(!texres) texres = &dummy_texres;
++      data.coord = coord;
++      data.target = texres;
++      data.do_preview = do_preview;
++      data.thread = thread;
++      data.which_output = which_output;
++      
++      ntreeExecTree(nodes, &data, thread);
++}
++
++void ntreeTexUpdatePreviews(bNodeTree* nodetree)
++{
++      Tex *tex;
++      float coord[] = {0,0,0};
++      TexResult dummy_texres;
++      
++      for(tex= G.main->tex.first; tex; tex= tex->id.next)
++              if(tex->nodetree == nodetree) break;
++      if(!tex) return;
++      
++      dummy_texres.nor = 0;
++      
++      ntreeBeginExecTree(nodetree);
++      ntreeTexExecTree(nodetree, &dummy_texres, coord, 1, 0, tex, 0);
++      ntreeEndExecTree(nodetree);
++      
++}
++
++char* ntreeTexOutputMenu(bNodeTree *ntree)
++{
++      bNode *node;
++      int len = 1;
++      char *str;
++      char ctrl[4];
++      int index = 0;
++      
++      for(node= ntree->nodes.first; node; node= node->next)
++              if(node->type == TEX_NODE_OUTPUT) {
++                      len += strlen( 
++                              ((TexNodeOutput*)node->storage)->name
++                      ) + strlen(" %xNNN|");
++                      index ++;
++                      
++                      if(node->custom1 > 999) {
++                              printf("Error: too many outputs");
++                              break;
++                      }
++              }
++                      
++      str = malloc(len * sizeof(char));
++      *str = 0;
++
++      for(node= ntree->nodes.first; node; node= node->next)
++              if(node->type == TEX_NODE_OUTPUT) {
++                      strcat(str, ((TexNodeOutput*)node->storage)->name);
++                      strcat(str, " %x");
++                      
++                      sprintf(ctrl, "%d", node->custom1);
++                      strcat(str, ctrl);
++                      
++                      if(--index)
++                              strcat(str, "|");
++                      else
++                              break;
++              }
++      
++      return str;
++}
++
++void ntreeTexAssignIndex(struct bNodeTree *ntree, struct bNode *node)
++{
++      bNode *tnode;
++      int index = 0;
++      
++      check_index:
++      for(tnode= ntree->nodes.first; tnode; tnode= tnode->next)
++              if(tnode->type == TEX_NODE_OUTPUT && tnode != node)
++                      if(tnode->custom1 == index) {
++                              index ++;
++                              goto check_index;
++                      }
++                      
++      node->custom1 = index;
++}
++
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..69cf20794c93296fb84542a192b62d0fad63dcba
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,104 @@@
++/**
++ *
++ * ***** 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): none yet.
++ *
++ * ***** END GPL LICENSE BLOCK *****
++ */
++
++#ifndef TEX_NODE_UTIL_H_
++#define TEX_NODE_UTIL_H_
++
++#include <math.h>
++#include <string.h>
++
++#include "MEM_guardedalloc.h"
++
++#include "DNA_action_types.h"
++#include "DNA_color_types.h"
++#include "DNA_ipo_types.h"
++#include "DNA_ID.h"
++#include "DNA_image_types.h"
++#include "DNA_material_types.h"
++#include "DNA_node_types.h"
++#include "DNA_object_types.h"
++#include "DNA_scene_types.h"
++#include "DNA_space_types.h"
++#include "DNA_screen_types.h"
++#include "DNA_texture_types.h"
++#include "DNA_userdef_types.h"
++
++#include "BKE_blender.h"
++#include "BKE_colortools.h"
++#include "BKE_global.h"
++#include "BKE_image.h"
++#include "BKE_main.h"
++#include "BKE_material.h"
++#include "BKE_texture.h"
++#include "BKE_utildefines.h"
++#include "BKE_library.h"
++
++#include "../SHD_node.h"
++#include "node_util.h"
++
++#include "BLI_arithb.h"
++#include "BLI_blenlib.h"
++#include "BLI_rand.h"
++#include "BLI_threads.h"
++
++#include "IMB_imbuf_types.h"
++#include "IMB_imbuf.h"
++
++#include "RE_pipeline.h"
++#include "RE_shader_ext.h"
++
++typedef struct TexCallData {
++      TexResult *target;
++      float *coord;
++      char do_preview;
++      short thread;
++      short which_output;
++} TexCallData;
++
++typedef void(*TexFn) (float *out, float *coord, bNode *node, bNodeStack **in, short thread);
++
++typedef struct TexDelegate {
++      TexFn fn;
++      bNode *node;
++      bNodeStack *in[MAX_SOCKET];
++      int type;
++} TexDelegate;
++
++void tex_call_delegate(TexDelegate*, float *out, float *coord, short thread);
++
++void tex_input_rgba(float *out, bNodeStack *in, float *coord, short thread);
++void tex_input_vec(float *out, bNodeStack *in, float *coord, short thread);
++float tex_input_value(bNodeStack *in, float *coord, short thread);
++
++void tex_output(bNode *node, bNodeStack **in, bNodeStack *out, TexFn texfn);
++void tex_do_preview(bNode *node, bNodeStack *ns, TexCallData *cdata);
++
++void ntreeTexUpdatePreviews( bNodeTree* nodetree );
++void ntreeTexExecTree(bNodeTree *nodes, TexResult *texres, float *coord, char do_preview, short thread, struct Tex *tex, short which_output);
++ 
++#endif
index 888474ffa18bd2c492563dc2212d3def7589644b,888474ffa18bd2c492563dc2212d3def7589644b..2cee2673a269f8591b4fea9f78e36b7ff2bbfead
@@@ -183,6 -183,6 +183,7 @@@ typedef struct ShadeInpu
  /* node shaders... */
  struct Tex;
  int   multitex_ext(struct Tex *tex, float *texvec, float *dxt, float *dyt, int osatex, struct TexResult *texres);
++int   multitex_thread(struct Tex *tex, float *texvec, float *dxt, float *dyt, int osatex, struct TexResult *texres, short thread, short which_output);
  
  /* shaded view and bake */
  struct Render;
index c6b11b4af9af8cde41004ff78fddb8a92f5d9796,c6b11b4af9af8cde41004ff78fddb8a92f5d9796..799f55210171b3618ae51b716525a95624d72849
@@@ -53,8 -53,8 +53,8 @@@ int shadeHaloFloat(HaloRen *har
  /**
   * Render the sky at pixel (x, y).
   */
--void shadeSkyPixel(float *collector, float fx, float fy);
--void shadeSkyView(float *colf, float *rco, float *view, float *dxyview);
++void shadeSkyPixel(float *collector, float fx, float fy, short thread);
++void shadeSkyView(float *colf, float *rco, float *view, float *dxyview, short thread);
  void shadeAtmPixel(struct SunSky *sunsky, float *collector, float fx, float fy, float distance);
  void shadeSunView(float *colf, float *view);
  /* ------------------------------------------------------------------------- */
index be5471e07c4d451a5b6ce0ce31d34697c0393a8d,be5471e07c4d451a5b6ce0ce31d34697c0393a8d..c254b76829294761c66f40b5f9e4d97292bcafa6
@@@ -53,11 -53,11 +53,12 @@@ struct ImBuf
  /* texture.h */
  
  void do_halo_tex(struct HaloRen *har, float xn, float yn, float *colf);
--void do_sky_tex(float *rco, float *lo, float *dxyview, float *hor, float *zen, float *blend, int skyflag);
++void do_sky_tex(float *rco, float *lo, float *dxyview, float *hor, float *zen, float *blend, int skyflag, short thread);
  void do_material_tex(struct ShadeInput *shi);
  void do_lamp_tex(LampRen *la, float *lavec, struct ShadeInput *shi, float *colf, int effect);
  
  void init_render_textures(Render *re);
++void end_render_textures(void);
  
  void render_realtime_texture(struct ShadeInput *shi, struct Image *ima);
  
index a9bc2131d77cb397725065dec35736325c9e7178,1a387ad74667bde1e8f9096fb6b5a854ac0c868c..e2692113d16bb4898e91bcd7771c9fa501e4d03a
@@@ -2271,6 -2272,6 +2271,7 @@@ static void displace_render_face(Rende
  
        shi.vlr= vlr;           /* current render face */
        shi.mat= vlr->mat;              /* current input material */
++      shi.thread= 0;
        
        /* Displace the verts, flag is set when done */
        if (!vlr->v1->flag)
@@@ -4406,6 -4407,6 +4407,7 @@@ void RE_Database_Free(Render *re
  
        end_radio_render();
        end_render_materials();
++      end_render_textures();
        
        if(re->wrld.aosphere) {
                MEM_freeN(re->wrld.aosphere);
index 60723963af93bf14ba67cbb06653192076acaa36,60723963af93bf14ba67cbb06653192076acaa36..af6093ab36c7c1ae84dcf45aa44ad00b40a55288
@@@ -511,7 -511,7 +511,7 @@@ static void fillBackgroundImage(float *
  }
  
  /* Only view vector is important here. Result goes to colf[3] */
--void shadeSkyView(float *colf, float *rco, float *view, float *dxyview)
++void shadeSkyView(float *colf, float *rco, float *view, float *dxyview, short thread)
  {
        float lo[3], zen[3], hor[3], blend, blendm;
        int skyflag;
                        SWAP(float, lo[1],  lo[2]);
                        
                }
--              do_sky_tex(rco, lo, dxyview, hor, zen, &blend, skyflag);
++              do_sky_tex(rco, lo, dxyview, hor, zen, &blend, skyflag, thread);
        }
        
        if(blend>1.0) blend= 1.0;
@@@ -607,7 -607,7 +607,7 @@@ void shadeSunView(float *colf, float *v
  /*
    Stuff the sky color into the collector.
   */
--void shadeSkyPixel(float *collector, float fx, float fy) 
++void shadeSkyPixel(float *collector, float fx, float fy, short thread
  {
        float view[3], dxyview[2];
  
                }
                
                /* get sky color in the collector */
--              shadeSkyView(collector, NULL, view, dxyview);
++              shadeSkyView(collector, NULL, view, dxyview, thread);
                collector[3] = 0.0f;
        }
        
index f822d41bb85c11b11fea21cf0a294cd3f6b8061a,f822d41bb85c11b11fea21cf0a294cd3f6b8061a..46a7a1c556c596aa1feab2e2e3de3e9cd7d6b7c6
@@@ -396,7 -396,7 +396,7 @@@ static void ray_fadeout_endcolor(float 
                VECCOPY(shi->view, vec);
                Normalize(shi->view);
                
--              shadeSkyView(col, isec->start, shi->view, NULL);
++              shadeSkyView(col, isec->start, shi->view, NULL, shi->thread);
                shadeSunView(col, shi->view);
        }
  }
@@@ -1627,7 -1627,7 +1627,7 @@@ static void ray_ao_qmc(ShadeInput *shi
                                shadfac[2]+= (1.0f-skyfac)*R.wrld.horb + skyfac*R.wrld.zenb;
                        }
                        else {  /* WO_AOSKYTEX */
--                              shadeSkyView(skycol, isec.start, view, dxyview);
++                              shadeSkyView(skycol, isec.start, view, dxyview, shi->thread);
                                shadeSunView(skycol, shi->view);
                                shadfac[0]+= skycol[0];
                                shadfac[1]+= skycol[1];
@@@ -1752,7 -1752,7 +1752,7 @@@ static void ray_ao_spheresamp(ShadeInpu
                                        shadfac[2]+= (1.0f-fac)*R.wrld.horb + fac*R.wrld.zenb;
                                }
                                else {  /* WO_AOSKYTEX */
--                                      shadeSkyView(skycol, isec.start, view, dxyview);
++                                      shadeSkyView(skycol, isec.start, view, dxyview, shi->thread);
                                        shadeSunView(skycol, shi->view);
                                        shadfac[0]+= skycol[0];
                                        shadfac[1]+= skycol[1];
index 1eb42bca5692da603b5125918acedb78310fc549,1eb42bca5692da603b5125918acedb78310fc549..c3b281f2a2335b99acf27b57352c75dc132ed1a8
@@@ -647,7 -647,7 +647,7 @@@ static void sky_tile(RenderPart *pa, Re
                                if(pass[3]<1.0f) {
                                        
                                        if(done==0) {
--                                              shadeSkyPixel(col, x, y);
++                                              shadeSkyPixel(col, x, y, pa->thread);
                                                done= 1;
                                        }
                                        
index 7ce66ff6d1265388d31aa082f0d162f5e5148999,7ce66ff6d1265388d31aa082f0d162f5e5148999..61e9d9cf4128948900e6c250c0a30c0e116cfa96
  #include "DNA_meshdata_types.h"
  #include "DNA_material_types.h"
  #include "DNA_image_types.h"
++#include "DNA_node_types.h"
  
  #include "IMB_imbuf_types.h"
  #include "IMB_imbuf.h"
  
  #include "BKE_image.h"
++#include "BKE_node.h"
  #include "BKE_plugin_types.h"
  #include "BKE_utildefines.h"
  
@@@ -114,6 -114,6 +116,10 @@@ void init_render_texture(Render *re, Te
                        }
                }
        }
++      
++      if(tex->nodetree && tex->use_nodes) {
++              ntreeBeginExecTree(tex->nodetree); /* has internal flag to detect it only does it once */
++      }
  }
  
  /* ------------------------------------------------------------------------- */
@@@ -129,6 -129,6 +135,20 @@@ void init_render_textures(Render *re
        }
  }
  
++void end_render_texture(Tex *tex)
++{
++      if(tex && tex->use_nodes && tex->nodetree)
++              ntreeEndExecTree(tex->nodetree);
++}
++
++void end_render_textures(void)
++{
++      Tex *tex;
++      for(tex= G.main->tex.first; tex; tex= tex->id.next)
++              if(tex->id.us)
++                      end_render_texture(tex);
++}
++
  /* ------------------------------------------------------------------------- */
  
  
@@@ -691,6 -691,6 +711,19 @@@ static float voronoiTex(Tex *tex, floa
  
  }
  
++/* ------------------------------------------------------------------------- */
++
++static int evalnodes(Tex *tex, float *texvec, TexResult *texres, short thread, short which_output)
++{
++      short rv = TEX_INT;
++      bNodeTree *nodes = tex->nodetree;
++      
++      ntreeTexExecTree(nodes, texres, texvec, 0, thread, tex, which_output);
++      
++      if(texres->nor) rv |= TEX_NOR;
++      rv |= TEX_RGB;
++      return rv;
++}
  
  /* ------------------------------------------------------------------------- */
  
@@@ -1130,13 -1130,13 +1163,17 @@@ static void do_2d_mapping(MTex *mtex, f
  
  /* ************************************** */
  
--static int multitex(Tex *tex, float *texvec, float *dxt, float *dyt, int osatex, TexResult *texres)
++static int multitex(Tex *tex, float *texvec, float *dxt, float *dyt, int osatex, TexResult *texres, short thread, short which_output)
  {
        float tmpvec[3];
        int retval=0; /* return value, int:0, col:1, nor:2, everything:3 */
  
        texres->talpha= 0;      /* is set when image texture returns alpha (considered premul) */
        
++      if(tex->use_nodes && tex->nodetree) {
++              retval = evalnodes(tex, texvec, texres, thread, which_output);
++      }
++      else
        switch(tex->type) {
        
        case 0:
   * the color values are set before using the r/g/b values, otherwise you may use uninitialized values - Campbell */
  int multitex_ext(Tex *tex, float *texvec, float *dxt, float *dyt, int osatex, TexResult *texres)
  {
--      
++      return multitex_thread(tex, texvec, dxt, dyt, osatex, texres, 0, 0);
++}
++
++int multitex_thread(Tex *tex, float *texvec, float *dxt, float *dyt, int osatex, TexResult *texres, short thread, short which_output)
++{
        if(tex==NULL) {
                memset(texres, 0, sizeof(TexResult));
                return 0;
                
                do_2d_mapping(&mtex, texvec_l, NULL, NULL, dxt_l, dyt_l);
  
--              return multitex(tex, texvec_l, dxt_l, dyt_l, osatex, texres);
++              return multitex(tex, texvec_l, dxt_l, dyt_l, osatex, texres, thread, which_output);
        }
        else
--              return multitex(tex, texvec, dxt, dyt, osatex, texres);
++              return multitex(tex, texvec, dxt, dyt, osatex, texres, thread, which_output);
  }
  
  /* ------------------------------------------------------------------------- */
@@@ -1671,7 -1671,7 +1712,7 @@@ void do_material_tex(ShadeInput *shi
                                }
                        }
  
--                      rgbnor= multitex(tex, texvec, dxt, dyt, shi->osatex, &texres);
++                      rgbnor= multitex(tex, texvec, dxt, dyt, shi->osatex, &texres, shi->thread, mtex->which_output);
  
                        /* texture output */
  
@@@ -2055,7 -2055,7 +2096,7 @@@ void do_halo_tex(HaloRen *har, float xn
  
        if(mtex->tex->type==TEX_IMAGE) do_2d_mapping(mtex, texvec, NULL, NULL, dxt, dyt);
        
--      rgb= multitex(mtex->tex, texvec, dxt, dyt, osatex, &texres);
++      rgb= multitex(mtex->tex, texvec, dxt, dyt, osatex, &texres, 0, mtex->which_output);
  
        /* texture output */
        if(rgb && (mtex->texflag & MTEX_RGBTOINT)) {
  /* ------------------------------------------------------------------------- */
  
  /* hor and zen are RGB vectors, blend is 1 float, should all be initialized */
--void do_sky_tex(float *rco, float *lo, float *dxyview, float *hor, float *zen, float *blend, int skyflag)
++void do_sky_tex(float *rco, float *lo, float *dxyview, float *hor, float *zen, float *blend, int skyflag, short thread)
  {
        MTex *mtex;
        TexResult texres= {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0, NULL};
                        /* texture */
                        if(mtex->tex->type==TEX_IMAGE) do_2d_mapping(mtex, texvec, NULL, NULL, dxt, dyt);
                
--                      rgb= multitex(mtex->tex, texvec, dxt, dyt, R.osa, &texres);
++                      rgb= multitex(mtex->tex, texvec, dxt, dyt, R.osa, &texres, thread, mtex->which_output);
                        
                        /* texture output */
                        if(rgb && (mtex->texflag & MTEX_RGBTOINT)) {
@@@ -2407,7 -2407,7 +2448,7 @@@ void do_lamp_tex(LampRen *la, float *la
                                do_2d_mapping(mtex, texvec, NULL, NULL, dxt, dyt);
                        }
                        
--                      rgb= multitex(tex, texvec, dxt, dyt, shi->osatex, &texres);
++                      rgb= multitex(tex, texvec, dxt, dyt, shi->osatex, &texres, shi->thread, mtex->which_output);
  
                        /* texture output */
                        if(rgb && (mtex->texflag & MTEX_RGBTOINT)) {
@@@ -2492,7 -2492,7 +2533,7 @@@ int externtex(MTex *mtex, float *vec, f
                do_2d_mapping(mtex, texvec, NULL, NULL, dxt, dyt);
        }
        
--      rgb= multitex(tex, texvec, dxt, dyt, 0, &texr);
++      rgb= multitex(tex, texvec, dxt, dyt, 0, &texr, 0, mtex->which_output);
        
        if(rgb) {
                texr.tin= (0.35*texr.tr+0.45*texr.tg+0.2*texr.tb);
index b192a591aa1de702e7baab4d8055562735aab290,b192a591aa1de702e7baab4d8055562735aab290..3b5e33eda593854a9996c02e1c1070b783b292c3
@@@ -421,10 -421,10 +421,6 @@@ class BlenderEnvironment(SConsEnvironme
                        lenv = self.Clone()
                        lenv.Append(CPPPATH=includes)
                        lenv.Append(CPPDEFINES=defines)
--                      if lenv['WITH_BF_GAMEENGINE']:
--                                      lenv.Append(CPPDEFINES=['GAMEBLENDER=1'])
--                      if lenv['WITH_BF_BULLET']:
--                                      lenv.Append(CPPDEFINES=['WITH_BULLET=1'])
                        if lenv['BF_DEBUG'] or (libname in quickdebug):
                                        lenv.Append(CFLAGS = lenv['BF_DEBUG_CFLAGS'])
                                        lenv.Append(CCFLAGS = lenv['BF_DEBUG_CCFLAGS'])
diff --cc tools/btools.py
index 6d16aeb4cdb7b0da4fdfb384e56c027f5f5830cc,6d16aeb4cdb7b0da4fdfb384e56c027f5f5830cc..66d5ecc6b9a1c7638fb0f30769f450a91da23108
@@@ -5,9 -5,9 +5,9 @@@ import SCons.Option
  
  import SCons.Variables
  try:
--    import subprocess
++      import subprocess
  except ImportError:
--    pass
++      pass
  import string
  import glob
  import shutil
@@@ -17,260 -17,260 +17,262 @@@ Variables = SCons.Variable
  BoolVariable = SCons.Variables.BoolVariable
  
  def print_arguments(args, bc):
--    if len(args):
--        for k,v in args.iteritems():
--            print '\t'+bc.OKBLUE+k+bc.ENDC+' = '+bc.OKGREEN + v + bc.ENDC
--    else:
--        print '\t'+bc.WARNING+'No  command-line arguments given'+bc.ENDC
++      if len(args):
++              for k,v in args.iteritems():
++                      print '\t'+bc.OKBLUE+k+bc.ENDC+' = '+bc.OKGREEN + v + bc.ENDC
++      else:
++              print '\t'+bc.WARNING+'No  command-line arguments given'+bc.ENDC
  
  def validate_arguments(args, bc):
--    opts_list = [
--            'WITH_BF_PYTHON', 'BF_PYTHON', 'BF_PYTHON_VERSION', 'BF_PYTHON_INC', 'BF_PYTHON_BINARY', 'BF_PYTHON_LIB', 'BF_PYTHON_LIBPATH', 'BF_PYTHON_LINKFLAGS', 'WITH_BF_STATICPYTHON', 'BF_PYTHON_LIB_STATIC',
--            'WITH_BF_OPENAL', 'BF_OPENAL', 'BF_OPENAL_INC', 'BF_OPENAL_LIB', 'BF_OPENAL_LIBPATH', 'WITH_BF_STATICOPENAL', 'BF_OPENAL_LIB_STATIC',
--            'WITH_BF_SDL', 'BF_SDL', 'BF_SDL_INC', 'BF_SDL_LIB', 'BF_SDL_LIBPATH',
--            'BF_PTHREADS', 'BF_PTHREADS_INC', 'BF_PTHREADS_LIB', 'BF_PTHREADS_LIBPATH',
--            'WITH_BF_FMOD',
--            'WITH_BF_OPENEXR', 'BF_OPENEXR', 'BF_OPENEXR_INC', 'BF_OPENEXR_LIB', 'BF_OPENEXR_LIBPATH', 'WITH_BF_STATICOPENEXR', 'BF_OPENEXR_LIB_STATIC',
--            'WITH_BF_DDS',
--            'WITH_BF_FFMPEG', 'BF_FFMPEG_LIB','BF_FFMPEG_EXTRA', 'BF_FFMPEG',  'BF_FFMPEG_INC',
--            'WITH_BF_OGG', 'BF_OGG', 'BF_OGG_LIB',
--            'WITH_BF_JPEG', 'BF_JPEG', 'BF_JPEG_INC', 'BF_JPEG_LIB', 'BF_JPEG_LIBPATH',
--            'WITH_BF_PNG', 'BF_PNG', 'BF_PNG_INC', 'BF_PNG_LIB', 'BF_PNG_LIBPATH',
--            'BF_TIFF', 'BF_TIFF_INC',
--            'WITH_BF_ZLIB', 'BF_ZLIB', 'BF_ZLIB_INC', 'BF_ZLIB_LIB', 'BF_ZLIB_LIBPATH',
--            'WITH_BF_INTERNATIONAL',
--            'BF_GETTEXT', 'BF_GETTEXT_INC', 'BF_GETTEXT_LIB', 'BF_GETTEXT_LIBPATH',
--            'WITH_BF_ICONV', 'BF_ICONV', 'BF_ICONV_INC', 'BF_ICONV_LIB', 'BF_ICONV_LIBPATH',
--            'WITH_BF_ODE', 'BF_ODE', 'BF_ODE_INC', 'BF_ODE_LIB',
--            'WITH_BF_GAMEENGINE', 'WITH_BF_BULLET', 'BF_BULLET', 'BF_BULLET_INC', 'BF_BULLET_LIB',
--            'BF_SOLID', 'BF_SOLID_INC', 'BF_WINTAB', 'BF_WINTAB_INC',
--            'WITH_BF_YAFRAY',
--            'WITH_BF_FREETYPE', 'BF_FREETYPE', 'BF_FREETYPE_INC', 'BF_FREETYPE_LIB', 'BF_FREETYPE_LIBPATH',
--            'WITH_BF_QUICKTIME', 'BF_QUICKTIME', 'BF_QUICKTIME_INC', 'BF_QUICKTIME_LIB', 'BF_QUICKTIME_LIBPATH',
--            'WITH_BF_STATICOPENGL', 'BF_OPENGL', 'BF_OPENGL_INC', 'BF_OPENGL_LIB', 'BF_OPENGL_LIBPATH', 'BF_OPENGL_LIB_STATIC', 'BF_OPENGL_LINKFLAGS',
--            'WITH_BF_FTGL', 'BF_FTGL', 'BF_FTGL_INC', 'BF_FTGL_LIB',
--            'WITH_BF_PLAYER',
--            'WITH_BF_NOBLENDER',
--            'WITH_BF_BINRELOC',
--            'CFLAGS', 'CCFLAGS', 'CXXFLAGS', 'CPPFLAGS',
--            'REL_CFLAGS', 'REL_CCFLAGS', 'REL_CXXFLAGS',
--            'BF_PROFILE_FLAGS', 'BF_PROFILE_FLAGS', 'BF_PROFILE_CXXFLAGS',
--            'BF_DEBUG_CFLAGS', 'BF_DEBUG_CCFLAGS', 'BF_DEBUG_CXXFLAGS',
--            'C_WARN', 'CC_WARN', 'CXX_WARN',
--            'LLIBS', 'PLATFORM_LINKFLAGS',
--            'LCGDIR',
--            'BF_CXX', 'WITH_BF_STATICCXX', 'BF_CXX_LIB_STATIC',
--            'WITH_BF_VERSE', 'BF_VERSE_INCLUDE',
--            'VERSE_BUILD_BINARY', 'VERSE_BUILD_DIR', 'VERSE_REGEN_PROTO',
--            'BF_TWEAK_MODE', 'BF_SPLIT_SRC',
--            'WITHOUT_BF_INSTALL',
--            'WITH_BF_OPENMP',
--            'WITHOUT_BF_INSTALL',
--            'BF_FANCY', 'BF_QUIET',
--            'BF_X264_CONFIG',
--            'BF_XVIDCORE_CONFIG',
--            'WITH_BF_DOCS',
--            'BF_NUMJOBS',
--            ]
--
--    arg_list = ['BF_DEBUG', 'BF_QUIET', 'BF_CROSS', 'BF_UPDATE',
--            'BF_INSTALLDIR', 'BF_TOOLSET', 'BF_BINNAME',
--            'BF_BUILDDIR', 'BF_FANCY', 'BF_QUICK', 'BF_PROFILE',
--            'BF_BSC', 'BF_CONFIG',
--            'BF_PRIORITYLIST', 'BF_BUILDINFO','CC', 'CXX', 'BF_QUICKDEBUG',
--            'BF_LISTDEBUG', 'LCGDIR', 'BF_X264_CONFIG', 'BF_XVIDCORE_CONFIG',
--            'BF_DOCDIR']
--
--    all_list = opts_list + arg_list
--    okdict = {}
--
--    for k,v in args.iteritems():
--        if k in all_list:
--            okdict[k] = v
--        else:
--            print '\t'+bc.WARNING+'Invalid argument: '+bc.ENDC+k+'='+v
--
--    return okdict
++      opts_list = [
++                      'WITH_BF_PYTHON', 'BF_PYTHON', 'BF_PYTHON_VERSION', 'BF_PYTHON_INC', 'BF_PYTHON_BINARY', 'BF_PYTHON_LIB', 'BF_PYTHON_LIBPATH', 'BF_PYTHON_LINKFLAGS', 'WITH_BF_STATICPYTHON', 'BF_PYTHON_LIB_STATIC',
++                      'WITH_BF_OPENAL', 'BF_OPENAL', 'BF_OPENAL_INC', 'BF_OPENAL_LIB', 'BF_OPENAL_LIBPATH', 'WITH_BF_STATICOPENAL', 'BF_OPENAL_LIB_STATIC',
++                      'WITH_BF_SDL', 'BF_SDL', 'BF_SDL_INC', 'BF_SDL_LIB', 'BF_SDL_LIBPATH',
++                      'BF_PTHREADS', 'BF_PTHREADS_INC', 'BF_PTHREADS_LIB', 'BF_PTHREADS_LIBPATH',
++                      'WITH_BF_FMOD',
++                      'WITH_BF_OPENEXR', 'BF_OPENEXR', 'BF_OPENEXR_INC', 'BF_OPENEXR_LIB', 'BF_OPENEXR_LIBPATH', 'WITH_BF_STATICOPENEXR', 'BF_OPENEXR_LIB_STATIC',
++                      'WITH_BF_DDS',
++                      'WITH_BF_FFMPEG', 'BF_FFMPEG_LIB','BF_FFMPEG_EXTRA', 'BF_FFMPEG',  'BF_FFMPEG_INC',
++                      'WITH_BF_OGG', 'BF_OGG', 'BF_OGG_LIB',
++                      'WITH_BF_JPEG', 'BF_JPEG', 'BF_JPEG_INC', 'BF_JPEG_LIB', 'BF_JPEG_LIBPATH',
++                      'WITH_BF_PNG', 'BF_PNG', 'BF_PNG_INC', 'BF_PNG_LIB', 'BF_PNG_LIBPATH',
++                      'BF_TIFF', 'BF_TIFF_INC', 'BF_TIFF_LIB', 'BF_TIFF_LIBPATH',
++                      'WITH_BF_ZLIB', 'BF_ZLIB', 'BF_ZLIB_INC', 'BF_ZLIB_LIB', 'BF_ZLIB_LIBPATH',
++                      'WITH_BF_INTERNATIONAL',
++                      'BF_GETTEXT', 'BF_GETTEXT_INC', 'BF_GETTEXT_LIB', 'BF_GETTEXT_LIBPATH',
++                      'WITH_BF_ICONV', 'BF_ICONV', 'BF_ICONV_INC', 'BF_ICONV_LIB', 'BF_ICONV_LIBPATH',
++                      'WITH_BF_ODE', 'BF_ODE', 'BF_ODE_INC', 'BF_ODE_LIB',
++                      'WITH_BF_GAMEENGINE', 'WITH_BF_BULLET', 'BF_BULLET', 'BF_BULLET_INC', 'BF_BULLET_LIB',
++                      'BF_SOLID', 'BF_SOLID_INC', 'BF_WINTAB', 'BF_WINTAB_INC',
++                      'WITH_BF_YAFRAY',
++                      'WITH_BF_FREETYPE', 'BF_FREETYPE', 'BF_FREETYPE_INC', 'BF_FREETYPE_LIB', 'BF_FREETYPE_LIBPATH',
++                      'WITH_BF_QUICKTIME', 'BF_QUICKTIME', 'BF_QUICKTIME_INC', 'BF_QUICKTIME_LIB', 'BF_QUICKTIME_LIBPATH',
++                      'WITH_BF_STATICOPENGL', 'BF_OPENGL', 'BF_OPENGL_INC', 'BF_OPENGL_LIB', 'BF_OPENGL_LIBPATH', 'BF_OPENGL_LIB_STATIC', 'BF_OPENGL_LINKFLAGS',
++                      'WITH_BF_FTGL', 'BF_FTGL', 'BF_FTGL_INC', 'BF_FTGL_LIB',
++                      'WITH_BF_PLAYER',
++                      'WITH_BF_NOBLENDER',
++                      'WITH_BF_BINRELOC',
++                      'CFLAGS', 'CCFLAGS', 'CXXFLAGS', 'CPPFLAGS',
++                      'REL_CFLAGS', 'REL_CCFLAGS', 'REL_CXXFLAGS',
++                      'BF_PROFILE_FLAGS', 'BF_PROFILE_FLAGS', 'BF_PROFILE_CXXFLAGS',
++                      'BF_DEBUG_CFLAGS', 'BF_DEBUG_CCFLAGS', 'BF_DEBUG_CXXFLAGS',
++                      'C_WARN', 'CC_WARN', 'CXX_WARN',
++                      'LLIBS', 'PLATFORM_LINKFLAGS',
++                      'LCGDIR',
++                      'BF_CXX', 'WITH_BF_STATICCXX', 'BF_CXX_LIB_STATIC',
++                      'WITH_BF_VERSE', 'BF_VERSE_INCLUDE',
++                      'VERSE_BUILD_BINARY', 'VERSE_BUILD_DIR', 'VERSE_REGEN_PROTO',
++                      'BF_TWEAK_MODE', 'BF_SPLIT_SRC',
++                      'WITHOUT_BF_INSTALL',
++                      'WITH_BF_OPENMP',
++                      'WITHOUT_BF_INSTALL',
++                      'BF_FANCY', 'BF_QUIET',
++                      'BF_X264_CONFIG',
++                      'BF_XVIDCORE_CONFIG',
++                      'WITH_BF_DOCS',
++                      'BF_NUMJOBS',
++                      ]
++
++      arg_list = ['BF_DEBUG', 'BF_QUIET', 'BF_CROSS', 'BF_UPDATE',
++                      'BF_INSTALLDIR', 'BF_TOOLSET', 'BF_BINNAME',
++                      'BF_BUILDDIR', 'BF_FANCY', 'BF_QUICK', 'BF_PROFILE',
++                      'BF_BSC', 'BF_CONFIG',
++                      'BF_PRIORITYLIST', 'BF_BUILDINFO','CC', 'CXX', 'BF_QUICKDEBUG',
++                      'BF_LISTDEBUG', 'LCGDIR', 'BF_X264_CONFIG', 'BF_XVIDCORE_CONFIG',
++                      'BF_DOCDIR']
++
++      all_list = opts_list + arg_list
++      okdict = {}
++
++      for k,v in args.iteritems():
++              if k in all_list:
++                      okdict[k] = v
++              else:
++                      print '\t'+bc.WARNING+'Invalid argument: '+bc.ENDC+k+'='+v
++
++      return okdict
  
  def print_targets(targs, bc):
--    if len(targs)>0:
--        for t in targs:
--            print '\t'+bc.OKBLUE+t+bc.ENDC
--    else:
--        print '\t'+bc.WARNING+'No targets given, using '+bc.ENDC+bc.OKGREEN+'default'+bc.ENDC
++      if len(targs)>0:
++              for t in targs:
++                      print '\t'+bc.OKBLUE+t+bc.ENDC
++      else:
++              print '\t'+bc.WARNING+'No targets given, using '+bc.ENDC+bc.OKGREEN+'default'+bc.ENDC
  
  def validate_targets(targs, bc):
--    valid_list = ['.', 'blender', 'blenderstatic', 'blenderplayer', 'webplugin',
--            'blendernogame', 'blenderstaticnogame', 'blenderlite', 'release',
--            'everything', 'clean', 'install-bin', 'install', 'nsis']
--    oklist = []
--    for t in targs:
--        if t in valid_list:
--            oklist.append(t)
--        else:
--            print '\t'+bc.WARNING+'Invalid target: '+bc.ENDC+t
--    return oklist
++      valid_list = ['.', 'blender', 'blenderstatic', 'blenderplayer', 'webplugin',
++                      'blendernogame', 'blenderstaticnogame', 'blenderlite', 'release',
++                      'everything', 'clean', 'install-bin', 'install', 'nsis']
++      oklist = []
++      for t in targs:
++              if t in valid_list:
++                      oklist.append(t)
++              else:
++                      print '\t'+bc.WARNING+'Invalid target: '+bc.ENDC+t
++      return oklist
  
  class ourSpawn:
--    def ourspawn(self, sh, escape, cmd, args, env):
--        newargs = string.join(args[1:], ' ')
--        cmdline = cmd + " " + newargs
--        startupinfo = subprocess.STARTUPINFO()
--        startupinfo.dwFlags |= subprocess.STARTF_USESHOWWINDOW
--        proc = subprocess.Popen(cmdline, stdin=subprocess.PIPE, stdout=subprocess.PIPE,
--            stderr=subprocess.PIPE, startupinfo=startupinfo, shell = False)
--        data, err = proc.communicate()
--        rv = proc.wait()
--        if rv:
--            print "====="
--            print err
--            print "====="
--        return rv
++      def ourspawn(self, sh, escape, cmd, args, env):
++              newargs = string.join(args[1:], ' ')
++              cmdline = cmd + " " + newargs
++              startupinfo = subprocess.STARTUPINFO()
++              startupinfo.dwFlags |= subprocess.STARTF_USESHOWWINDOW
++              proc = subprocess.Popen(cmdline, stdin=subprocess.PIPE, stdout=subprocess.PIPE,
++                      stderr=subprocess.PIPE, startupinfo=startupinfo, shell = False)
++              data, err = proc.communicate()
++              rv = proc.wait()
++              if rv:
++                      print "====="
++                      print err
++                      print "====="
++              return rv
  
  def SetupSpawn( env ):
--    buf = ourSpawn()
--    buf.ourenv = env
--    env['SPAWN'] = buf.ourspawn
++      buf = ourSpawn()
++      buf.ourenv = env
++      env['SPAWN'] = buf.ourspawn
  
  
  def read_opts(cfg, args):
--    localopts = Variables.Variables(cfg, args)
--    localopts.AddVariables(
--        ('VERSE_BUILD_BINARY', 'Build a release or debug binary.', 'release'),
--        ('VERSE_BUILD_DIR', 'Target directory for intermediate files.', "${BF_BUILDDIR}/extern/verse"),
--        ('VERSE_REGEN_PROTO', 'Whether to regenerate the protocol files', 'yes'),
--        (BoolVariable('WITH_BF_VERSE', 'Use VERSE if true', False)),
--        ('BF_VERSE_INCLUDE', 'verse include dir', '/usr/include'),
--        ('LCGDIR', 'location of cvs lib dir'),
--        ('VERSE_BUILD_BINARY', 'Build a release or debug binary.', 'release'),
--        ('VERSE_BUILD_DIR', 'Target directory for intermediate files.', "${BF_BUILDDIR}/extern/verse"),
--        ('VERSE_REGEN_PROTO', 'Whether to regenerate the protocol files', 'yes'),
--        ('BF_DEBUG_LIBS', 'list of libraries to build with debug symbols'),
--
--        (BoolVariable('WITH_BF_PYTHON', 'Compile with python', True)),
--        ('BF_PYTHON', 'base path for python', ''),
--        ('BF_PYTHON_VERSION', 'Python version to use', ''),
--        ('BF_PYTHON_INC', 'include path for Python headers', ''),
--        ('BF_PYTHON_BINARY', 'Path to the Python interpreter', ''),
--        ('BF_PYTHON_LIB', 'Python library', ''),
--        ('BF_PYTHON_LIB_STATIC', 'Python static libraries', ''),
--        ('BF_PYTHON_LIBPATH', 'Library path', ''),
--        ('BF_PYTHON_LINKFLAGS', 'Python link flags', ''),
--        (BoolVariable('WITH_BF_STATICPYTHON', 'Staticly link to python', False)),
--
--        (BoolVariable('BF_NO_ELBEEM', 'Disable Fluid Sim', False)),
--        (BoolVariable('WITH_BF_YAFRAY', 'Enable Yafray', True)),
--
--        (BoolVariable('WITH_BF_OPENAL', 'Use OpenAL if true', False)),
--        ('BF_OPENAL', 'base path for OpenAL', ''),
--        ('BF_OPENAL_INC', 'include path for python headers', ''),
--        ('BF_OPENAL_LIB', 'Path to OpenAL library', ''),
--        ('BF_OPENAL_LIB_STATIC', 'Path to OpenAL static library', ''),
--        ('BF_OPENAL_LIBPATH', 'Path to OpenAL library', ''),
--        (BoolVariable('WITH_BF_STATICOPENAL', 'Staticly link to openal', False)),
--
--        (BoolVariable('WITH_BF_SDL', 'Use SDL if true', False)),
--        ('BF_SDL', 'SDL base path', ''),
--        ('BF_SDL_INC', 'SDL include path', ''),     #$(shell $(BF_SDL)/bin/sdl-config --cflags)
--        ('BF_SDL_LIB', 'SDL library', ''),      #$(shell $(BF_SDL)/bin/sdl-config --libs) -lSDL_mixer
--        ('BF_SDL_LIBPATH', 'SDL library path', ''),
--
--        ('BF_PTHREADS', 'Pthreads base path', ''),
--        ('BF_PTHREADS_INC', 'Pthreads include path', ''),
--        ('BF_PTHREADS_LIB', 'Pthreads library', ''),
--        ('BF_PTHREADS_LIBPATH', 'Pthreads library path', ''),
--
--        (BoolVariable('WITH_BF_FMOD', 'Use FMOD if true', False)),
--        #  BF_FMOD = $(LCGDIR)/fmod
--
--        (BoolVariable('WITH_BF_OPENEXR', 'Use OPENEXR if true', True)),
--        (BoolVariable('WITH_BF_STATICOPENEXR', 'Staticly link to OpenEXR', False)),
--        ('BF_OPENEXR', 'OPENEXR base path', ''),
--        ('BF_OPENEXR_INC', 'OPENEXR include path', ''),
--        ('BF_OPENEXR_LIB', 'OPENEXR library', ''),
--        ('BF_OPENEXR_LIBPATH', 'OPENEXR library path', ''),
--        ('BF_OPENEXR_LIB_STATIC', 'OPENEXR static library', ''),
--
--        (BoolVariable('WITH_BF_DDS', 'Use DDS if true', True)),
--
--        (BoolVariable('WITH_BF_FFMPEG', 'Use FFMPEG if true', False)),
--        ('BF_FFMPEG', 'FFMPEG base path', ''),
--        ('BF_FFMPEG_LIB', 'FFMPEG library', ''),
--        ('BF_FFMPEG_EXTRA', 'FFMPEG flags that must be preserved', ''),
--
--        ('BF_FFMPEG_INC', 'FFMPEG includes', ''),
--        ('BF_FFMPEG_LIBPATH', 'FFMPEG library path', ''),
--        
--        (BoolVariable('WITH_BF_OGG', 'Use OGG, THEORA, VORBIS in FFMPEG if true',
--                    False)),
--        ('BF_OGG', 'OGG base path', ''),
--        ('BF_OGG_LIB', 'OGG library', ''),
--
--        (BoolVariable('WITH_BF_JPEG', 'Use JPEG if true', True)),
--        ('BF_JPEG', 'JPEG base path', ''),
--        ('BF_JPEG_INC', 'JPEG include path', ''),
--        ('BF_JPEG_LIB', 'JPEG library', ''),
--        ('BF_JPEG_LIBPATH', 'JPEG library path', ''),
--
--        (BoolVariable('WITH_BF_OPENJPEG', 'Use OPENJPEG if true', False)),
--        ('BF_OPENJPEG', 'OPENJPEG base path', ''),
--        ('BF_OPENJPEG_INC', 'OPENJPEG include path', ''),
--        ('BF_OPENJPEG_LIB', 'OPENJPEG library', ''),
--        ('BF_OPENJPEG_LIBPATH', 'OPENJPEG library path', ''),
--
--        (BoolVariable('WITH_BF_REDCODE', 'Use REDCODE if true', False)),
--        ('BF_REDCODE', 'REDCODE base path', ''),
--        ('BF_REDCODE_INC', 'REDCODE include path', ''),
--        ('BF_REDCODE_LIB', 'REDCODE library', ''),
--        ('BF_REDCODE_LIBPATH', 'REDCODE library path', ''),
--
--        (BoolVariable('WITH_BF_PNG', 'Use PNG if true', True)),
--        ('BF_PNG', 'PNG base path', ''),
--        ('BF_PNG_INC', 'PNG include path', ''),
--        ('BF_PNG_LIB', 'PNG library', ''),
--        ('BF_PNG_LIBPATH', 'PNG library path', ''),
--
--        ('BF_TIFF', 'TIFF base path', ''),
--        ('BF_TIFF_INC', 'TIFF include path', ''),
--
--        (BoolVariable('WITH_BF_ZLIB', 'Use ZLib if true', True)),
--        ('BF_ZLIB', 'ZLib base path', ''),
--        ('BF_ZLIB_INC', 'ZLib include path', ''),
--        ('BF_ZLIB_LIB', 'ZLib library', ''),
--        ('BF_ZLIB_LIBPATH', 'ZLib library path', ''),
--
--        (BoolVariable('WITH_BF_INTERNATIONAL', 'Use Gettext and Freetype if true', True)),
--
--        ('BF_GETTEXT', 'gettext base path', ''),
--        ('BF_GETTEXT_INC', 'gettext include path', ''),
--        ('BF_GETTEXT_LIB', 'gettext library', ''),
--        ('BF_GETTEXT_LIBPATH', 'gettext library path', ''),
--        
--        (BoolVariable('WITH_BF_ICONV', 'Use iconv if true', True)),
--        ('BF_ICONV', 'iconv base path', ''),
--        ('BF_ICONV_INC', 'iconv include path', ''),
--        ('BF_ICONV_LIB', 'iconv library', ''),
--        ('BF_ICONV_LIBPATH', 'iconv library path', ''),
--        
--        (BoolVariable('WITH_BF_GAMEENGINE', 'Build with gameengine' , True)),
--
--        (BoolVariable('WITH_BF_ODE', 'Use ODE if true', True)),
--        ('BF_ODE', 'ODE base path', ''),
--        ('BF_ODE_INC', 'ODE include path' , ''),
--        ('BF_ODE_LIB', 'ODE library', ''),
--
--        (BoolVariable('WITH_BF_BULLET', 'Use Bullet if true', True)),
--        ('BF_BULLET', 'Bullet base dir', ''),
--        ('BF_BULLET_INC', 'Bullet include path', ''),
--        ('BF_BULLET_LIB', 'Bullet library', ''),
--        
--        ('BF_SOLID', 'Solid base dir', '#/extern/solid'),
--        ('BF_SOLID_INC', 'Solid include path', ''),
--        ('BF_WINTAB', 'WinTab base dir', ''),
--        ('BF_WINTAB_INC', 'WinTab include dir', ''),
--        ('BF_CXX', 'c++ base path for libstdc++, only used when static linking', ''),
--        (BoolVariable('WITH_BF_STATICCXX', 'static link to stdc++', False)),
--        ('BF_CXX_LIB_STATIC', 'static library path for stdc++', ''),
++      localopts = Variables.Variables(cfg, args)
++      localopts.AddVariables(
++              ('VERSE_BUILD_BINARY', 'Build a release or debug binary.', 'release'),
++              ('VERSE_BUILD_DIR', 'Target directory for intermediate files.', "${BF_BUILDDIR}/extern/verse"),
++              ('VERSE_REGEN_PROTO', 'Whether to regenerate the protocol files', 'yes'),
++              (BoolVariable('WITH_BF_VERSE', 'Use VERSE if true', False)),
++              ('BF_VERSE_INCLUDE', 'verse include dir', '/usr/include'),
++              ('LCGDIR', 'location of cvs lib dir'),
++              ('VERSE_BUILD_BINARY', 'Build a release or debug binary.', 'release'),
++              ('VERSE_BUILD_DIR', 'Target directory for intermediate files.', "${BF_BUILDDIR}/extern/verse"),
++              ('VERSE_REGEN_PROTO', 'Whether to regenerate the protocol files', 'yes'),
++              ('BF_DEBUG_LIBS', 'list of libraries to build with debug symbols'),
++
++              (BoolVariable('WITH_BF_PYTHON', 'Compile with python', True)),
++              ('BF_PYTHON', 'base path for python', ''),
++              ('BF_PYTHON_VERSION', 'Python version to use', ''),
++              ('BF_PYTHON_INC', 'include path for Python headers', ''),
++              ('BF_PYTHON_BINARY', 'Path to the Python interpreter', ''),
++              ('BF_PYTHON_LIB', 'Python library', ''),
++              ('BF_PYTHON_LIB_STATIC', 'Python static libraries', ''),
++              ('BF_PYTHON_LIBPATH', 'Library path', ''),
++              ('BF_PYTHON_LINKFLAGS', 'Python link flags', ''),
++              (BoolVariable('WITH_BF_STATICPYTHON', 'Staticly link to python', False)),
++
++              (BoolVariable('BF_NO_ELBEEM', 'Disable Fluid Sim', False)),
++              (BoolVariable('WITH_BF_YAFRAY', 'Enable Yafray', True)),
++
++              (BoolVariable('WITH_BF_OPENAL', 'Use OpenAL if true', False)),
++              ('BF_OPENAL', 'base path for OpenAL', ''),
++              ('BF_OPENAL_INC', 'include path for python headers', ''),
++              ('BF_OPENAL_LIB', 'Path to OpenAL library', ''),
++              ('BF_OPENAL_LIB_STATIC', 'Path to OpenAL static library', ''),
++              ('BF_OPENAL_LIBPATH', 'Path to OpenAL library', ''),
++              (BoolVariable('WITH_BF_STATICOPENAL', 'Staticly link to openal', False)),
++
++              (BoolVariable('WITH_BF_SDL', 'Use SDL if true', False)),
++              ('BF_SDL', 'SDL base path', ''),
++              ('BF_SDL_INC', 'SDL include path', ''),  #$(shell $(BF_SDL)/bin/sdl-config --cflags)
++              ('BF_SDL_LIB', 'SDL library', ''),        #$(shell $(BF_SDL)/bin/sdl-config --libs) -lSDL_mixer
++              ('BF_SDL_LIBPATH', 'SDL library path', ''),
++
++              ('BF_PTHREADS', 'Pthreads base path', ''),
++              ('BF_PTHREADS_INC', 'Pthreads include path', ''),
++              ('BF_PTHREADS_LIB', 'Pthreads library', ''),
++              ('BF_PTHREADS_LIBPATH', 'Pthreads library path', ''),
++
++              (BoolVariable('WITH_BF_FMOD', 'Use FMOD if true', False)),
++              #  BF_FMOD = $(LCGDIR)/fmod
++
++              (BoolVariable('WITH_BF_OPENEXR', 'Use OPENEXR if true', True)),
++              (BoolVariable('WITH_BF_STATICOPENEXR', 'Staticly link to OpenEXR', False)),
++              ('BF_OPENEXR', 'OPENEXR base path', ''),
++              ('BF_OPENEXR_INC', 'OPENEXR include path', ''),
++              ('BF_OPENEXR_LIB', 'OPENEXR library', ''),
++              ('BF_OPENEXR_LIBPATH', 'OPENEXR library path', ''),
++              ('BF_OPENEXR_LIB_STATIC', 'OPENEXR static library', ''),
++
++              (BoolVariable('WITH_BF_DDS', 'Use DDS if true', True)),
++
++              (BoolVariable('WITH_BF_FFMPEG', 'Use FFMPEG if true', False)),
++              ('BF_FFMPEG', 'FFMPEG base path', ''),
++              ('BF_FFMPEG_LIB', 'FFMPEG library', ''),
++              ('BF_FFMPEG_EXTRA', 'FFMPEG flags that must be preserved', ''),
++
++              ('BF_FFMPEG_INC', 'FFMPEG includes', ''),
++              ('BF_FFMPEG_LIBPATH', 'FFMPEG library path', ''),
++              
++              (BoolVariable('WITH_BF_OGG', 'Use OGG, THEORA, VORBIS in FFMPEG if true',
++                                      False)),
++              ('BF_OGG', 'OGG base path', ''),
++              ('BF_OGG_LIB', 'OGG library', ''),
++
++              (BoolVariable('WITH_BF_JPEG', 'Use JPEG if true', True)),
++              ('BF_JPEG', 'JPEG base path', ''),
++              ('BF_JPEG_INC', 'JPEG include path', ''),
++              ('BF_JPEG_LIB', 'JPEG library', ''),
++              ('BF_JPEG_LIBPATH', 'JPEG library path', ''),
++
++              (BoolVariable('WITH_BF_OPENJPEG', 'Use OPENJPEG if true', False)),
++              ('BF_OPENJPEG', 'OPENJPEG base path', ''),
++              ('BF_OPENJPEG_INC', 'OPENJPEG include path', ''),
++              ('BF_OPENJPEG_LIB', 'OPENJPEG library', ''),
++              ('BF_OPENJPEG_LIBPATH', 'OPENJPEG library path', ''),
++
++              (BoolVariable('WITH_BF_REDCODE', 'Use REDCODE if true', False)),
++              ('BF_REDCODE', 'REDCODE base path', ''),
++              ('BF_REDCODE_INC', 'REDCODE include path', ''),
++              ('BF_REDCODE_LIB', 'REDCODE library', ''),
++              ('BF_REDCODE_LIBPATH', 'REDCODE library path', ''),
++
++              (BoolVariable('WITH_BF_PNG', 'Use PNG if true', True)),
++              ('BF_PNG', 'PNG base path', ''),
++              ('BF_PNG_INC', 'PNG include path', ''),
++              ('BF_PNG_LIB', 'PNG library', ''),
++              ('BF_PNG_LIBPATH', 'PNG library path', ''),
++
++              ('BF_TIFF', 'TIFF base path', ''),
++              ('BF_TIFF_INC', 'TIFF include path', ''),
++              ('BF_TIFF_LIB', 'TIFF library', ''),
++              ('BF_TIFF_LIBPATH', 'TIFF library path', ''),
++
++              (BoolVariable('WITH_BF_ZLIB', 'Use ZLib if true', True)),
++              ('BF_ZLIB', 'ZLib base path', ''),
++              ('BF_ZLIB_INC', 'ZLib include path', ''),
++              ('BF_ZLIB_LIB', 'ZLib library', ''),
++              ('BF_ZLIB_LIBPATH', 'ZLib library path', ''),
++
++              (BoolVariable('WITH_BF_INTERNATIONAL', 'Use Gettext and Freetype if true', True)),
++
++              ('BF_GETTEXT', 'gettext base path', ''),
++              ('BF_GETTEXT_INC', 'gettext include path', ''),
++              ('BF_GETTEXT_LIB', 'gettext library', ''),
++              ('BF_GETTEXT_LIBPATH', 'gettext library path', ''),
++              
++              (BoolVariable('WITH_BF_ICONV', 'Use iconv if true', True)),
++              ('BF_ICONV', 'iconv base path', ''),
++              ('BF_ICONV_INC', 'iconv include path', ''),
++              ('BF_ICONV_LIB', 'iconv library', ''),
++              ('BF_ICONV_LIBPATH', 'iconv library path', ''),
++              
++              (BoolVariable('WITH_BF_GAMEENGINE', 'Build with gameengine' , True)),
++
++              (BoolVariable('WITH_BF_ODE', 'Use ODE if true', True)),
++              ('BF_ODE', 'ODE base path', ''),
++              ('BF_ODE_INC', 'ODE include path' , ''),
++              ('BF_ODE_LIB', 'ODE library', ''),
++
++              (BoolVariable('WITH_BF_BULLET', 'Use Bullet if true', True)),
++              ('BF_BULLET', 'Bullet base dir', ''),
++              ('BF_BULLET_INC', 'Bullet include path', ''),
++              ('BF_BULLET_LIB', 'Bullet library', ''),
++              
++              ('BF_SOLID', 'Solid base dir', '#/extern/solid'),
++              ('BF_SOLID_INC', 'Solid include path', ''),
++              ('BF_WINTAB', 'WinTab base dir', ''),
++              ('BF_WINTAB_INC', 'WinTab include dir', ''),
++              ('BF_CXX', 'c++ base path for libstdc++, only used when static linking', ''),
++              (BoolVariable('WITH_BF_STATICCXX', 'static link to stdc++', False)),
++              ('BF_CXX_LIB_STATIC', 'static library path for stdc++', ''),
  ##
  ##WITH_BF_NSPR = True
  ##BF_NSPR = $(LCGDIR)/nspr
  ##BF_PARANOID = True
  ##
  ### enable freetype2 support for text objects
--        (BoolVariable('WITH_BF_FREETYPE', 'Use FreeType2 if true', False)),
--        ('BF_FREETYPE', 'Freetype base path', ''),
--        ('BF_FREETYPE_INC', 'Freetype include path', ''),
--        ('BF_FREETYPE_LIB', 'Freetype library', ''),
--        ('BF_FREETYPE_LIBPATH', 'Freetype library path', ''),
--
--        (BoolVariable('WITH_BF_OPENMP', 'Use OpenMP if true', False)),
--
--        (BoolVariable('WITH_BF_QUICKTIME', 'Use QuickTime if true', False)),
--        ('BF_QUICKTIME', 'QuickTime base path', ''),
--        ('BF_QUICKTIME_INC', 'QuickTime include path', ''),
--        ('BF_QUICKTIME_LIB', 'QuickTime library', ''),
--        ('BF_QUICKTIME_LIBPATH', 'QuickTime library path', ''),
--
--        (BoolVariable('WITH_BF_STATICOPENGL', 'Use MESA if true', True)),
--        ('BF_OPENGL', 'OpenGL base path', ''),
--        ('BF_OPENGL_INC', 'OpenGL include path', ''),
--        ('BF_OPENGL_LIB', 'OpenGL libraries', ''),
--        ('BF_OPENGL_LIBPATH', 'OpenGL library path', ''),
--        ('BF_OPENGL_LIB_STATIC', 'OpenGL static libraries', ''),
--        ('BF_OPENGL_LINKFLAGS', 'OpenGL link flags', ''),
--        
--        (BoolVariable('WITH_BF_FTGL', 'Use FTGL if true', True)),
--        ('BF_FTGL', 'FTGL base path', ''),
--        ('BF_FTGL_INC', 'FTGL include path', ''),
--        ('BF_FTGL_LIB', 'FTGL libraries', ''),
--
--        (BoolVariable('WITH_BF_PLAYER', 'Build blenderplayer if true', False)),
--        (BoolVariable('WITH_BF_NOBLENDER', 'Do not build blender if true', False)),
--
--        ('CFLAGS', 'C only flags', ''),
--        ('CCFLAGS', 'Generic C and C++ flags', ''),
--        ('CXXFLAGS', 'C++ only flags', ''),
--        ('CPPFLAGS', 'Defines', ''),
--        ('REL_CFLAGS', 'C only release flags', ''),
--        ('REL_CCFLAGS', 'Generic C and C++ release flags', ''),
--        ('REL_CXXFLAGS', 'C++ only release flags', ''),
--
--        ('C_WARN', 'C warning flags', ''),
--        ('CC_WARN', 'Generic C and C++ warning flags', ''),
--        ('CXX_WARN', 'C++ only warning flags', ''),
--
--        ('LLIBS', 'Platform libs', ''),
--        ('PLATFORM_LINKFLAGS', 'Platform linkflags', ''),
--
--        (BoolVariable('BF_PROFILE', 'Add profiling information if true', False)),
--        ('BF_PROFILE_CFLAGS', 'C only profiling flags', ''),
--        ('BF_PROFILE_CCFLAGS', 'C and C++ profiling flags', ''),
--        ('BF_PROFILE_CXXFLAGS', 'C++ only profiling flags', ''),
--
--        (BoolVariable('BF_DEBUG', 'Add debug flags if true', False)),
--        ('BF_DEBUG_CFLAGS', 'C only debug flags', ''),
--        ('BF_DEBUG_CCFLAGS', 'C and C++ debug flags', ''),
--        ('BF_DEBUG_CXXFLAGS', 'C++ only debug flags', ''),
--
--        (BoolVariable('BF_BSC', 'Create .bsc files (msvc only)', True)),
--
--        ('BF_BUILDDIR', 'Build dir', ''),
--        ('BF_INSTALLDIR', 'Installation dir', ''),
--        ('BF_DOCDIR', 'Dir where BPy documentation will be created', ''),
--
--        ('CC', 'C compiler to use', ''),
--        ('CXX', 'C++ compiler to use', ''),
--
--        (BoolVariable('BF_BUILDINFO', 'Buildtime in splash if true', True)),
--
--        (BoolVariable('BF_TWEAK_MODE', 'Enable tweak mode if true', False)),
--        (BoolVariable('BF_SPLIT_SRC', 'Split src lib into several chunks if true', False)),
--        (BoolVariable('WITHOUT_BF_INSTALL', 'dont install if true', False)),
--        (BoolVariable('BF_FANCY', 'Enable fancy output if true', True)),
--        (BoolVariable('BF_QUIET', 'Enable silent output if true', True)),
--        (BoolVariable('WITH_BF_BINRELOC', 'Enable relocatable binary (linux only)', False)),
--
--        ('BF_X264_CONFIG', 'configuration flags for x264', ''),
--        ('BF_XVIDCORE_CONFIG', 'configuration flags for xvidcore', ''),
--        (BoolVariable('WITH_BF_DOCS', 'Generate API documentation', False)),
--        
--        ('BF_CONFIG', 'SCons python config file used to set default options', 'user_config.py'),
--        ('BF_NUMJOBS', 'Number of build processes to spawn', '1')
--
--    ) # end of opts.AddOptions()
--
--    return localopts
++              (BoolVariable('WITH_BF_FREETYPE', 'Use FreeType2 if true', False)),
++              ('BF_FREETYPE', 'Freetype base path', ''),
++              ('BF_FREETYPE_INC', 'Freetype include path', ''),
++              ('BF_FREETYPE_LIB', 'Freetype library', ''),
++              ('BF_FREETYPE_LIBPATH', 'Freetype library path', ''),
++
++              (BoolVariable('WITH_BF_OPENMP', 'Use OpenMP if true', False)),
++
++              (BoolVariable('WITH_BF_QUICKTIME', 'Use QuickTime if true', False)),
++              ('BF_QUICKTIME', 'QuickTime base path', ''),
++              ('BF_QUICKTIME_INC', 'QuickTime include path', ''),
++              ('BF_QUICKTIME_LIB', 'QuickTime library', ''),
++              ('BF_QUICKTIME_LIBPATH', 'QuickTime library path', ''),
++
++              (BoolVariable('WITH_BF_STATICOPENGL', 'Use MESA if true', True)),
++              ('BF_OPENGL', 'OpenGL base path', ''),
++              ('BF_OPENGL_INC', 'OpenGL include path', ''),
++              ('BF_OPENGL_LIB', 'OpenGL libraries', ''),
++              ('BF_OPENGL_LIBPATH', 'OpenGL library path', ''),
++              ('BF_OPENGL_LIB_STATIC', 'OpenGL static libraries', ''),
++              ('BF_OPENGL_LINKFLAGS', 'OpenGL link flags', ''),
++              
++              (BoolVariable('WITH_BF_FTGL', 'Use FTGL if true', True)),
++              ('BF_FTGL', 'FTGL base path', ''),
++              ('BF_FTGL_INC', 'FTGL include path', ''),
++              ('BF_FTGL_LIB', 'FTGL libraries', ''),
++
++              (BoolVariable('WITH_BF_PLAYER', 'Build blenderplayer if true', False)),
++              (BoolVariable('WITH_BF_NOBLENDER', 'Do not build blender if true', False)),
++
++              ('CFLAGS', 'C only flags', ''),
++              ('CCFLAGS', 'Generic C and C++ flags', ''),
++              ('CXXFLAGS', 'C++ only flags', ''),
++              ('CPPFLAGS', 'Defines', ''),
++              ('REL_CFLAGS', 'C only release flags', ''),
++              ('REL_CCFLAGS', 'Generic C and C++ release flags', ''),
++              ('REL_CXXFLAGS', 'C++ only release flags', ''),
++
++              ('C_WARN', 'C warning flags', ''),
++              ('CC_WARN', 'Generic C and C++ warning flags', ''),
++              ('CXX_WARN', 'C++ only warning flags', ''),
++
++              ('LLIBS', 'Platform libs', ''),
++              ('PLATFORM_LINKFLAGS', 'Platform linkflags', ''),
++
++              (BoolVariable('BF_PROFILE', 'Add profiling information if true', False)),
++              ('BF_PROFILE_CFLAGS', 'C only profiling flags', ''),
++              ('BF_PROFILE_CCFLAGS', 'C and C++ profiling flags', ''),
++              ('BF_PROFILE_CXXFLAGS', 'C++ only profiling flags', ''),
++
++              (BoolVariable('BF_DEBUG', 'Add debug flags if true', False)),
++              ('BF_DEBUG_CFLAGS', 'C only debug flags', ''),
++              ('BF_DEBUG_CCFLAGS', 'C and C++ debug flags', ''),
++              ('BF_DEBUG_CXXFLAGS', 'C++ only debug flags', ''),
++
++              (BoolVariable('BF_BSC', 'Create .bsc files (msvc only)', True)),
++
++              ('BF_BUILDDIR', 'Build dir', ''),
++              ('BF_INSTALLDIR', 'Installation dir', ''),
++              ('BF_DOCDIR', 'Dir where BPy documentation will be created', ''),
++
++              ('CC', 'C compiler to use', ''),
++              ('CXX', 'C++ compiler to use', ''),
++
++              (BoolVariable('BF_BUILDINFO', 'Buildtime in splash if true', True)),
++
++              (BoolVariable('BF_TWEAK_MODE', 'Enable tweak mode if true', False)),
++              (BoolVariable('BF_SPLIT_SRC', 'Split src lib into several chunks if true', False)),
++              (BoolVariable('WITHOUT_BF_INSTALL', 'dont install if true', False)),
++              (BoolVariable('BF_FANCY', 'Enable fancy output if true', True)),
++              (BoolVariable('BF_QUIET', 'Enable silent output if true', True)),
++              (BoolVariable('WITH_BF_BINRELOC', 'Enable relocatable binary (linux only)', False)),
++
++              ('BF_X264_CONFIG', 'configuration flags for x264', ''),
++              ('BF_XVIDCORE_CONFIG', 'configuration flags for xvidcore', ''),
++              (BoolVariable('WITH_BF_DOCS', 'Generate API documentation', False)),
++              
++              ('BF_CONFIG', 'SCons python config file used to set default options', 'user_config.py'),
++              ('BF_NUMJOBS', 'Number of build processes to spawn', '1')
++
++      ) # end of opts.AddOptions()
++
++      return localopts
  
  def NSIS_print(target, source, env):
--    return "Creating NSIS installer for Blender 3D"
++      return "Creating NSIS installer for Blender 3D"
  
  def NSIS_Installer(target=None, source=None, env=None):
  
--    if env['OURPLATFORM'] != 'win32-vc' and env['OURPLATFORM'] != 'win32-mingw':
--        print "NSIS installer is only available on Windows."
--        Exit()
--        
--    start_dir = os.getcwd()
--    rel_dir = start_dir + "\\release\\windows\\installer\\"
--    install_base_dir = start_dir + "\\"
--    
--    if not os.path.exists(install_base_dir+env['BF_INSTALLDIR']+'/plugins/include'):
--        os.mkdir(install_base_dir+env['BF_INSTALLDIR']+'/plugins/include')
--        
--    for f in glob.glob('source/blender/blenpluginapi/*.h'):
--        shutil.copy(f,install_base_dir+env['BF_INSTALLDIR']+'/plugins/include')
--
--    shutil.copy('source/blender/blenpluginapi/plugin.def',install_base_dir+env['BF_INSTALLDIR']+'/plugins/include/')
--    
--    os.chdir("release")
--    v = open("VERSION")
--    version = v.read()[:-1]   
--    shortver = version.split('.')[0] + version.split('.')[1]
--    v.close()
--
--    #### change to suit install dir ####
--    inst_dir = install_base_dir + env['BF_INSTALLDIR']
--    
--    os.chdir("windows/installer")
--
--    ns = open("00.sconsblender.nsi","r")
--
--    ns_cnt = str(ns.read())
--    ns.close()
--
--    # do root
--    rootlist = []
--    rootdir = os.listdir(inst_dir+"\\")
--    for rootitem in rootdir:
--        if os.path.isdir(inst_dir+"\\"+ rootitem) == 0:
--            rootlist.append("File \"" + os.path.normpath(inst_dir) + "\\" + rootitem+"\"")
--    rootstring = string.join(rootlist, "\n  ")
--    rootstring += "\n\n"
--    ns_cnt = string.replace(ns_cnt, "[ROOTDIRCONTS]", rootstring)
--
--    # do delete items
--    delrootlist = []
--    for rootitem in rootdir:
--        if os.path.isdir(inst_dir + rootitem) == 0:
--            delrootlist.append("Delete $INSTDIR\\" + rootitem)
--    delrootstring = string.join(delrootlist, "\n ")
--    delrootstring += "\n"
--    ns_cnt = string.replace(ns_cnt, "[DELROOTDIRCONTS]", delrootstring)
--
--    # do scripts
--    scriptlist = []
--    scriptpath = "%s%s" % (inst_dir, "\\.blender\\scripts")
--    scriptdir = os.listdir(scriptpath)
--    for scriptitem in scriptdir:
--        scriptfile = "%s\\%s" % (scriptpath, scriptitem)
--        if os.path.isdir(scriptfile) == 0:
--            scriptfile = os.path.normpath(scriptfile)
--            scriptlist.append("File \"%s\"" % scriptfile)
--    scriptstring = string.join(scriptlist, "\n  ")
--    scriptstring += "\n\n"
--    ns_cnt = string.replace(ns_cnt, "[SCRIPTCONTS]", scriptstring)
--
--    # do scripts\bpymodules
--    bpymodlist = []
--    bpymodpath = "%s%s" % (inst_dir, "\\.blender\\scripts\\bpymodules")
--    bpymoddir = os.listdir(bpymodpath)
--
--    for bpymoditem in bpymoddir:
--        bpymodfile = "%s\\%s" % (bpymodpath, bpymoditem)
--        if os.path.isdir(bpymodfile) == 0:
--            bpymodfile = os.path.normpath(bpymodfile)
--            bpymodlist.append("File \"%s\"" % bpymodfile)
--    bpymodstring = string.join(bpymodlist, "\n  ")
--    bpymodstring += "\n\n"
--    ns_cnt = string.replace(ns_cnt, "[SCRIPTMODCONTS]", bpymodstring)
--
--    # do scripts\bpymodules\colladaimex
--    colladalist = []
--    bpymodpath = "%s%s" % (inst_dir, "\\.blender\\scripts\\bpymodules\\ColladaImEx")
--    bpymoddir = os.listdir(bpymodpath)
--
--    for bpymoditem in bpymoddir:
--        bpymodfile = "%s\\%s" % (bpymodpath, bpymoditem)
--        if os.path.isdir(bpymodfile) == 0:
--            bpymodfile=os.path.normpath(bpymodfile)
--            colladalist.append("File \"%s\"" % bpymodfile)
--    bpymodstring = string.join(colladalist, "\n  ")
--    bpymodstring += "\n\n"
--    ns_cnt = string.replace(ns_cnt, "[SCRIPTMODCOLLADACONT]", bpymodstring)
--
--    # do scripts\bpydata
--    bpydatalist = []
--    bpydatapath = "%s%s" % (inst_dir, "\\.blender\\scripts\\bpydata")
--    bpydatadir = os.listdir(bpydatapath)
--    for bpydataitem in bpydatadir:
--        bpydatafile = "%s\\%s" % (bpydatapath, bpydataitem)
--        if os.path.isdir(bpydatafile) == 0:
--            bpydatalist.append("File \"%s\"" % bpydatafile)
--    bpydatastring = string.join(bpydatalist, "\n  ")
--    bpydatastring += "\n\n"
--    ns_cnt = string.replace(ns_cnt, "[SCRIPTDATACONTS]", bpydatastring)
--
--    # do plugins\include
--    plugincludelist = []
--    plugincludepath = "%s%s" % (inst_dir, "\\plugins\\include")
--    plugincludedir = os.listdir(plugincludepath)
--    for plugincludeitem in plugincludedir:
--        plugincludefile = "%s\\%s" % (plugincludepath, plugincludeitem)
--        if os.path.isdir(plugincludefile) == 0:
--            if plugincludefile.find('.h') or plugincludefile.find('.DEF'):
--                plugincludefile = os.path.normpath(plugincludefile)
--                plugincludelist.append("File \"%s\"" % plugincludefile)
--    plugincludestring = string.join(plugincludelist, "\n  ")
--    plugincludestring += "\n\n"
--    ns_cnt = string.replace(ns_cnt, "[PLUGINCONTS]", plugincludestring)
--
--    # do scripts\bpydata\config
--    cfglist = []
--    cfgpath = "%s%s" % (inst_dir, "\\.blender\\scripts\\bpydata\\config")
--    cfgdir = os.listdir(cfgpath)
--    for cfgitem in cfgdir:
--        cfgfile = "%s\\%s" % (cfgpath, cfgitem)
--        if os.path.isdir(cfgfile) == 0:
--            cfglist.append("File \"%s\"" % cfgfile)
--    cfgstring = string.join(cfglist, "\n  ")
--    cfgstring += "\n\n"
--    ns_cnt = string.replace(ns_cnt, "[SCRIPTDATACFGCONTS]", cfgstring)
--
--    # do dotblender
--    dotblendlist = []
--    dotblenddir = os.listdir(inst_dir+"\\.blender")
--    for dotblenditem in dotblenddir:
--        if os.path.isdir(inst_dir + "\\.blender\\" + dotblenditem) == 0:
--            dotblendlist.append("File \"" + os.path.normpath(inst_dir) + "\\.blender\\" +
--            dotblenditem+"\"")
--    dotblendstring = string.join(dotblendlist, "\n  ")
--    dotblendstring += "\n\n"
--    ns_cnt = string.replace(ns_cnt, "[DOTBLENDERCONTS]", dotblendstring)
--
--    # do language files
--    langlist = []
--    langfiles = []
--    langdir = os.listdir(inst_dir + "\\.blender\\locale")
--    for langitem in langdir:
--        if os.path.isdir(inst_dir + "\\.blender\\locale\\" + langitem) == 1:
--            langfiles.append("SetOutPath $BLENDERHOME\\.blender\\locale\\" + langitem + "\\LC_MESSAGES")
--            langfiles.append("File \"" + os.path.normpath(inst_dir) + "\\.blender\\locale\\"
--                    + langitem + "\\LC_MESSAGES\\blender.mo\"")
--    langstring = string.join(langfiles, "\n  ")
--    langstring += "\n\n"
--    ns_cnt = string.replace(ns_cnt, "[LANGUAGECONTS]", langstring)
--
--    # var replacements
--    ns_cnt = string.replace(ns_cnt, "DISTDIR", os.path.normpath(inst_dir+"\\"))
--    ns_cnt = string.replace(ns_cnt, "SHORTVER", shortver)
--    ns_cnt = string.replace(ns_cnt, "VERSION", version)
--    ns_cnt = string.replace(ns_cnt, "RELDIR", os.path.normpath(rel_dir))
--
--    tmpnsi = os.path.normpath(install_base_dir+os.sep+env['BF_BUILDDIR']+os.sep+"00.blender_tmp.nsi")
--    new_nsis = open(tmpnsi, 'w')
--    new_nsis.write(ns_cnt)
--    new_nsis.close()
--
--    os.chdir(start_dir)
--
--    cmdline = "makensis " + "\""+tmpnsi+"\""
--
--    startupinfo = subprocess.STARTUPINFO()
--    startupinfo.dwFlags |= subprocess.STARTF_USESHOWWINDOW
--    proc = subprocess.Popen(cmdline, stdin=subprocess.PIPE, stdout=subprocess.PIPE,
--        stderr=subprocess.PIPE, startupinfo=startupinfo, shell = True)
--    data, err = proc.communicate()
--    rv = proc.wait()
--
--    if rv != 0:
--        print
--        print data.strip().split("\n")[-1]
--    return rv
++      if env['OURPLATFORM'] != 'win32-vc' and env['OURPLATFORM'] != 'win32-mingw':
++              print "NSIS installer is only available on Windows."
++              Exit()
++              
++      start_dir = os.getcwd()
++      rel_dir = start_dir + "\\release\\windows\\installer\\"
++      install_base_dir = start_dir + "\\"
++      
++      if not os.path.exists(install_base_dir+env['BF_INSTALLDIR']+'/plugins/include'):
++              os.mkdir(install_base_dir+env['BF_INSTALLDIR']+'/plugins/include')
++              
++      for f in glob.glob('source/blender/blenpluginapi/*.h'):
++              shutil.copy(f,install_base_dir+env['BF_INSTALLDIR']+'/plugins/include')
++
++      shutil.copy('source/blender/blenpluginapi/plugin.def',install_base_dir+env['BF_INSTALLDIR']+'/plugins/include/')
++      
++      os.chdir("release")
++      v = open("VERSION")
++      version = v.read()[:-1] 
++      shortver = version.split('.')[0] + version.split('.')[1]
++      v.close()
++
++      #### change to suit install dir ####
++      inst_dir = install_base_dir + env['BF_INSTALLDIR']
++      
++      os.chdir("windows/installer")
++
++      ns = open("00.sconsblender.nsi","r")
++
++      ns_cnt = str(ns.read())
++      ns.close()
++
++      # do root
++      rootlist = []
++      rootdir = os.listdir(inst_dir+"\\")
++      for rootitem in rootdir:
++              if os.path.isdir(inst_dir+"\\"+ rootitem) == 0:
++                      rootlist.append("File \"" + os.path.normpath(inst_dir) + "\\" + rootitem+"\"")
++      rootstring = string.join(rootlist, "\n  ")
++      rootstring += "\n\n"
++      ns_cnt = string.replace(ns_cnt, "[ROOTDIRCONTS]", rootstring)
++
++      # do delete items
++      delrootlist = []
++      for rootitem in rootdir:
++              if os.path.isdir(inst_dir + rootitem) == 0:
++                      delrootlist.append("Delete $INSTDIR\\" + rootitem)
++      delrootstring = string.join(delrootlist, "\n ")
++      delrootstring += "\n"
++      ns_cnt = string.replace(ns_cnt, "[DELROOTDIRCONTS]", delrootstring)
++
++      # do scripts
++      scriptlist = []
++      scriptpath = "%s%s" % (inst_dir, "\\.blender\\scripts")
++      scriptdir = os.listdir(scriptpath)
++      for scriptitem in scriptdir:
++              scriptfile = "%s\\%s" % (scriptpath, scriptitem)
++              if os.path.isdir(scriptfile) == 0:
++                      scriptfile = os.path.normpath(scriptfile)
++                      scriptlist.append("File \"%s\"" % scriptfile)
++      scriptstring = string.join(scriptlist, "\n  ")
++      scriptstring += "\n\n"
++      ns_cnt = string.replace(ns_cnt, "[SCRIPTCONTS]", scriptstring)
++
++      # do scripts\bpymodules
++      bpymodlist = []
++      bpymodpath = "%s%s" % (inst_dir, "\\.blender\\scripts\\bpymodules")
++      bpymoddir = os.listdir(bpymodpath)
++
++      for bpymoditem in bpymoddir:
++              bpymodfile = "%s\\%s" % (bpymodpath, bpymoditem)
++              if os.path.isdir(bpymodfile) == 0:
++                      bpymodfile = os.path.normpath(bpymodfile)
++                      bpymodlist.append("File \"%s\"" % bpymodfile)
++      bpymodstring = string.join(bpymodlist, "\n  ")
++      bpymodstring += "\n\n"
++      ns_cnt = string.replace(ns_cnt, "[SCRIPTMODCONTS]", bpymodstring)
++
++      # do scripts\bpymodules\colladaimex
++      colladalist = []
++      bpymodpath = "%s%s" % (inst_dir, "\\.blender\\scripts\\bpymodules\\ColladaImEx")
++      bpymoddir = os.listdir(bpymodpath)
++
++      for bpymoditem in bpymoddir:
++              bpymodfile = "%s\\%s" % (bpymodpath, bpymoditem)
++              if os.path.isdir(bpymodfile) == 0:
++                      bpymodfile=os.path.normpath(bpymodfile)
++                      colladalist.append("File \"%s\"" % bpymodfile)
++      bpymodstring = string.join(colladalist, "\n  ")
++      bpymodstring += "\n\n"
++      ns_cnt = string.replace(ns_cnt, "[SCRIPTMODCOLLADACONT]", bpymodstring)
++
++      # do scripts\bpydata
++      bpydatalist = []
++      bpydatapath = "%s%s" % (inst_dir, "\\.blender\\scripts\\bpydata")
++      bpydatadir = os.listdir(bpydatapath)
++      for bpydataitem in bpydatadir:
++              bpydatafile = "%s\\%s" % (bpydatapath, bpydataitem)
++              if os.path.isdir(bpydatafile) == 0:
++                      bpydatalist.append("File \"%s\"" % bpydatafile)
++      bpydatastring = string.join(bpydatalist, "\n  ")
++      bpydatastring += "\n\n"
++      ns_cnt = string.replace(ns_cnt, "[SCRIPTDATACONTS]", bpydatastring)
++
++      # do plugins\include
++      plugincludelist = []
++      plugincludepath = "%s%s" % (inst_dir, "\\plugins\\include")
++      plugincludedir = os.listdir(plugincludepath)
++      for plugincludeitem in plugincludedir:
++              plugincludefile = "%s\\%s" % (plugincludepath, plugincludeitem)
++              if os.path.isdir(plugincludefile) == 0:
++                      if plugincludefile.find('.h') or plugincludefile.find('.DEF'):
++                              plugincludefile = os.path.normpath(plugincludefile)
++                              plugincludelist.append("File \"%s\"" % plugincludefile)
++      plugincludestring = string.join(plugincludelist, "\n  ")
++      plugincludestring += "\n\n"
++      ns_cnt = string.replace(ns_cnt, "[PLUGINCONTS]", plugincludestring)
++
++      # do scripts\bpydata\config
++      cfglist = []
++      cfgpath = "%s%s" % (inst_dir, "\\.blender\\scripts\\bpydata\\config")
++      cfgdir = os.listdir(cfgpath)
++      for cfgitem in cfgdir:
++              cfgfile = "%s\\%s" % (cfgpath, cfgitem)
++              if os.path.isdir(cfgfile) == 0:
++                      cfglist.append("File \"%s\"" % cfgfile)
++      cfgstring = string.join(cfglist, "\n  ")
++      cfgstring += "\n\n"
++      ns_cnt = string.replace(ns_cnt, "[SCRIPTDATACFGCONTS]", cfgstring)
++
++      # do dotblender
++      dotblendlist = []
++      dotblenddir = os.listdir(inst_dir+"\\.blender")
++      for dotblenditem in dotblenddir:
++              if os.path.isdir(inst_dir + "\\.blender\\" + dotblenditem) == 0:
++                      dotblendlist.append("File \"" + os.path.normpath(inst_dir) + "\\.blender\\" +
++                      dotblenditem+"\"")
++      dotblendstring = string.join(dotblendlist, "\n  ")
++      dotblendstring += "\n\n"
++      ns_cnt = string.replace(ns_cnt, "[DOTBLENDERCONTS]", dotblendstring)
++
++      # do language files
++      langlist = []
++      langfiles = []
++      langdir = os.listdir(inst_dir + "\\.blender\\locale")
++      for langitem in langdir:
++              if os.path.isdir(inst_dir + "\\.blender\\locale\\" + langitem) == 1:
++                      langfiles.append("SetOutPath $BLENDERHOME\\.blender\\locale\\" + langitem + "\\LC_MESSAGES")
++                      langfiles.append("File \"" + os.path.normpath(inst_dir) + "\\.blender\\locale\\"
++                                      + langitem + "\\LC_MESSAGES\\blender.mo\"")
++      langstring = string.join(langfiles, "\n  ")
++      langstring += "\n\n"
++      ns_cnt = string.replace(ns_cnt, "[LANGUAGECONTS]", langstring)
++
++      # var replacements
++      ns_cnt = string.replace(ns_cnt, "DISTDIR", os.path.normpath(inst_dir+"\\"))
++      ns_cnt = string.replace(ns_cnt, "SHORTVER", shortver)
++      ns_cnt = string.replace(ns_cnt, "VERSION", version)
++      ns_cnt = string.replace(ns_cnt, "RELDIR", os.path.normpath(rel_dir))
++
++      tmpnsi = os.path.normpath(install_base_dir+os.sep+env['BF_BUILDDIR']+os.sep+"00.blender_tmp.nsi")
++      new_nsis = open(tmpnsi, 'w')
++      new_nsis.write(ns_cnt)
++      new_nsis.close()
++
++      os.chdir(start_dir)
++
++      cmdline = "makensis " + "\""+tmpnsi+"\""
++
++      startupinfo = subprocess.STARTUPINFO()
++      startupinfo.dwFlags |= subprocess.STARTF_USESHOWWINDOW
++      proc = subprocess.Popen(cmdline, stdin=subprocess.PIPE, stdout=subprocess.PIPE,
++              stderr=subprocess.PIPE, startupinfo=startupinfo, shell = True)
++      data, err = proc.communicate()
++      rv = proc.wait()
++
++      if rv != 0:
++              print
++              print data.strip().split("\n")[-1]
++      return rv