Ver Fonte

added header files:
PI constant
ZERO constants
useful material color floats
get current seconds since EPOCH function
ReAntTweakBar library

Added examples folder:
ReAntTweakBar example with static option


Former-commit-id: 487db0163d9e8231726792a1c79e0a08781b10d5

jalec há 13 anos atrás
pai
commit
67da1c1e96

+ 4 - 0
PI.h

@@ -0,0 +1,4 @@
+namespace igl
+{
+  const double PI = 3.1415926535897932384626433832795;
+}

+ 867 - 0
ReAntTweakBar.h

@@ -0,0 +1,867 @@
+// ReAntTweakBar is a minimal wrapper for the AntTweakBar library that allows
+// "bars" to be saved and load from disk. Changing your existing app that users
+// AntTweakBar to use ReAntTweakBar is trivial.
+// 
+// Many (but not all) variable types are supported. I'll try to keep track them
+// here:
+//   TW_TYPE_BOOLCPP
+//   TW_TYPE_QUAT4F
+//   TW_TYPE_COLOR4F
+//   TW_TYPE_COLOR3F
+//   TW_TYPE_DIR3F
+//   TW_TYPE_BOOL32
+//   TW_TYPE_INT32
+//   TW_TYPE_FLOAT
+//   TW_TYPE_DOUBLE
+//   and
+//   custom TwTypes made with TwDefineEnum
+// 
+// I'm working on adding the rest on an as-needed basis. Adding a new type only
+// requires changes in a few places...
+// 
+//
+// Copyright Alec Jacobson, 2011
+//
+
+// This allows the user to have a non-global, static installation of
+// AntTweakBar
+#ifdef STATIC_ANTTWEAKBAR
+#  include "AntTweakBar.h"
+#else
+#  include <AntTweakBar.h>
+#endif
+
+#include <vector>
+#include <string>
+
+namespace igl
+{
+
+  TwType ReTwDefineEnum(const char *name, const TwEnumVal *enumValues, unsigned int nbValues);
+  
+  struct ReTwRWItem
+  {
+    const char * name;
+    TwType type;
+    void * var;
+    ReTwRWItem(
+      const char * name,
+      TwType type, 
+      void *var)
+    {
+      this->name = name;
+      this->type = type;
+      this->var = var;
+    }
+  };
+  
+  struct ReTwCBItem
+  {
+    const char * name;
+    TwSetVarCallback setCallback;
+    TwGetVarCallback getCallback;
+    void * clientData;
+    TwType type;
+    ReTwCBItem(
+      const char * name,
+      TwType type, 
+      TwSetVarCallback setCallback,
+      TwGetVarCallback getCallback,
+      void * clientData)
+    {
+      this->name = name;
+      this->type = type;
+      this->setCallback = setCallback;
+      this->getCallback = getCallback;
+      this->clientData = clientData;
+    }
+  };
+  
+  class ReTwBar
+  {
+    // VARIABLES
+    // Should be private, but seeing as I'm not going to implement all of the
+    // AntTweakBar public functions right away, I'll expose this so that at
+    // anytime AntTweakBar functions can be called directly on the bar
+    public:
+      TwBar * bar;
+    private:
+      std::vector<ReTwRWItem> rw_items;
+      std::vector<ReTwCBItem> cb_items;
+  
+    // WRAPPERS FOR ANTTWEAKBAR FUNCTIONS 
+    public:
+      void TwNewBar(const char *barName);
+      int TwAddVarRW(
+        const char *name, 
+        TwType type, 
+        void *var, 
+        const char *def,
+        const bool record=true);
+      int TwAddVarCB(
+        const char *name, 
+        TwType type, 
+        TwSetVarCallback setCallback, 
+        TwGetVarCallback getCallback, 
+        void *clientData, 
+        const char *def,
+        const bool record=true);
+      // Wrappers for convenience (not recorded, just passed on)
+      int TwAddVarRO(const char *name, TwType type, void *var, const char *def);
+      int TwAddButton(
+        const char *name, 
+        TwButtonCallback buttonCallback, 
+        void *clientData, 
+        const char *def);
+      int TwSetParam(
+        const char *varName, 
+        const char *paramName, 
+        TwParamValueType paramValueType, 
+        unsigned int inValueCount, 
+        const void *inValues);
+      int TwGetParam(
+        const char *varName, 
+        const char *paramName, 
+        TwParamValueType paramValueType, 
+        unsigned int outValueMaxCount, 
+        void *outValues);
+      int TwRefreshBar();
+  
+  
+    // IO FUNCTIONS
+    public:
+      // Save current items to file
+      // Input:
+      //   file_name  name of file to save data to, can be null which means print
+      //   to stdout
+      // Return:
+      //   true only if there were no (fatal) errors
+      bool save(const char *file_name);
+      std::string get_value_as_string(
+        void * var, 
+        TwType type);
+      // Load into current items from file
+      // Input:
+      //   file_name  name of input file to load
+      // Return:
+      //   true only if there were no (fatal) errors
+      bool load(const char *file_name);
+      // Get TwType from string
+      // Input
+      //   type_str  string of type 
+      // Output
+      //   type  TwType converted from string
+      // Returns
+      //   true only if string matched a valid type
+      bool type_from_string(const char *type_str, TwType & type);
+      // I realize that I mixing std::string and const char * all over the place.
+      // What can you do...
+      bool set_value_from_string(
+        const char * name, 
+        TwType type, 
+        const char * value_str);
+  };
+
+};
+
+// List of TwBar functions
+//TW_API TwBar *      TW_CALL TwNewBar(const char *barName);
+//TW_API int          TW_CALL TwDeleteBar(TwBar *bar);
+//TW_API int          TW_CALL TwDeleteAllBars();
+//TW_API int          TW_CALL TwSetTopBar(const TwBar *bar);
+//TW_API TwBar *      TW_CALL TwGetTopBar();
+//TW_API int          TW_CALL TwSetBottomBar(const TwBar *bar);
+//TW_API TwBar *      TW_CALL TwGetBottomBar();
+//TW_API const char * TW_CALL TwGetBarName(TwBar *bar);
+//TW_API int          TW_CALL TwGetBarCount();
+//TW_API TwBar *      TW_CALL TwGetBarByIndex(int barIndex);
+//TW_API TwBar *      TW_CALL TwGetBarByName(const char *barName);
+//TW_API int          TW_CALL TwRefreshBar(TwBar *bar);
+//
+//TW_API int      TW_CALL TwAddVarRW(TwBar *bar, const char *name, TwType type, void *var, const char *def);
+//TW_API int      TW_CALL TwAddVarRO(TwBar *bar, const char *name, TwType type, const void *var, const char *def);
+//TW_API int      TW_CALL TwAddVarCB(TwBar *bar, const char *name, TwType type, TwSetVarCallback setCallback, TwGetVarCallback getCallback, void *clientData, const char *def);
+//TW_API int      TW_CALL TwAddButton(TwBar *bar, const char *name, TwButtonCallback callback, void *clientData, const char *def);
+//TW_API int      TW_CALL TwAddSeparator(TwBar *bar, const char *name, const char *def);
+//TW_API int      TW_CALL TwRemoveVar(TwBar *bar, const char *name);
+//TW_API int      TW_CALL TwRemoveAllVars(TwBar *bar);
+
+// Implementation
+
+#include <cstdio>
+#include <sstream>
+#include <map>
+
+#define MAX_CB_VAR_SIZE 10
+// Max line size for reading files
+#define MAX_LINE 1000
+#define MAX_WORD 100
+
+// GLOBAL WRAPPERS
+namespace igl
+{
+  std::map<TwType,std::pair<const char *,std::vector<TwEnumVal> > > ReTw_custom_types;
+}
+
+TwType igl::ReTwDefineEnum(
+  const char *name, 
+  const TwEnumVal *enumValues, 
+  unsigned int nbValues)
+{
+  // copy enum valus into vector
+  std::vector<TwEnumVal> enum_vals;
+  enum_vals.resize(nbValues);
+  for(unsigned int j = 0; j<nbValues;j++)
+  {
+    enum_vals[j] = enumValues[j];
+  }
+  TwType type = TwDefineEnum(name,enumValues,nbValues);
+
+  ReTw_custom_types[type] = 
+    std::pair<const char *,std::vector<TwEnumVal> >(name,enum_vals);
+  return type;
+}
+
+namespace igl
+{
+  struct ReTwTypeString
+  {
+    TwType type;
+    const char * type_str;
+  };
+
+  #define RETW_NUM_DEFAULT_TYPE_STRINGS 23
+  ReTwTypeString ReTwDefaultTypeStrings[RETW_NUM_DEFAULT_TYPE_STRINGS] = 
+  {
+    {TW_TYPE_UNDEF,"TW_TYPE_UNDEF"},
+    {TW_TYPE_BOOLCPP,"TW_TYPE_BOOLCPP"},
+    {TW_TYPE_BOOL8,"TW_TYPE_BOOL8"},
+    {TW_TYPE_BOOL16,"TW_TYPE_BOOL16"},
+    {TW_TYPE_BOOL32,"TW_TYPE_BOOL32"},
+    {TW_TYPE_CHAR,"TW_TYPE_CHAR"},
+    {TW_TYPE_INT8,"TW_TYPE_INT8"},
+    {TW_TYPE_UINT8,"TW_TYPE_UINT8"},
+    {TW_TYPE_INT16,"TW_TYPE_INT16"},
+    {TW_TYPE_UINT16,"TW_TYPE_UINT16"},
+    {TW_TYPE_INT32,"TW_TYPE_INT32"},
+    {TW_TYPE_UINT32,"TW_TYPE_UINT32"},
+    {TW_TYPE_FLOAT,"TW_TYPE_FLOAT"},
+    {TW_TYPE_DOUBLE,"TW_TYPE_DOUBLE"},
+    {TW_TYPE_COLOR32,"TW_TYPE_COLOR32"},
+    {TW_TYPE_COLOR3F,"TW_TYPE_COLOR3F"},
+    {TW_TYPE_COLOR4F,"TW_TYPE_COLOR4F"},
+    {TW_TYPE_CDSTRING,"TW_TYPE_CDSTRING"},
+    {TW_TYPE_STDSTRING,"TW_TYPE_STDSTRING"},
+    {TW_TYPE_QUAT4F,"TW_TYPE_QUAT4F"},
+    {TW_TYPE_QUAT4D,"TW_TYPE_QUAT4D"},
+    {TW_TYPE_DIR3F,"TW_TYPE_DIR3F"},
+    {TW_TYPE_DIR3D,"TW_TYPE_DIR3D"}
+  };
+}
+
+
+// BAR WRAPPERS
+void igl::ReTwBar::TwNewBar(const char *barName)
+{
+  // double colon without anything in front of it means look for this in the
+  // global namespace... I hope...
+  this->bar = ::TwNewBar(barName);
+}
+
+int igl::ReTwBar::TwAddVarRW(
+  const char *name, 
+  TwType type, 
+  void *var, 
+  const char *def,
+  const bool record)
+{
+  int ret = ::TwAddVarRW(this->bar,name,type,var,def);
+  if(ret && record)
+  {
+    rw_items.push_back(ReTwRWItem(name,type,var));
+  }
+  return ret;
+}
+
+int igl::ReTwBar::TwAddVarCB(
+  const char *name, 
+  TwType type, 
+  TwSetVarCallback setCallback, 
+  TwGetVarCallback getCallback, 
+  void *clientData, 
+  const char *def,
+  const bool record)
+{
+  int ret = 
+    ::TwAddVarCB(this->bar,name,type,setCallback,getCallback,clientData,def);
+  if(ret && record)
+  {
+    cb_items.push_back(ReTwCBItem(name,type,setCallback,getCallback,clientData));
+  }
+  return ret;
+}
+
+int igl::ReTwBar::TwAddVarRO(
+  const char *name, 
+  TwType type, 
+  void *var, 
+  const char *def)
+{
+  int ret = ::TwAddVarRO(this->bar,name,type,var,def);
+  // Read only variables are not recorded
+  //if(ret)
+  //{
+  //  rw_items.push_back(ReTwRWItem(name,type,var));
+  //}
+  return ret;
+}
+
+int igl::ReTwBar::TwAddButton(
+  const char *name, 
+  TwButtonCallback buttonCallback, 
+  void *clientData, 
+  const char *def)
+{
+  int ret = 
+    ::TwAddButton(this->bar,name,buttonCallback,clientData,def);
+  // buttons are not recorded
+  //if(ret)
+  //{
+  //  cb_items.push_back(ReTwCBItem(name,type,setCallback,getCallback,clientData));
+  //}
+  return ret;
+}
+
+int igl::ReTwBar::TwSetParam(
+  const char *varName, 
+  const char *paramName, 
+  TwParamValueType paramValueType, 
+  unsigned int inValueCount, 
+  const void *inValues)
+{
+  // For now just pass these along
+  return 
+    ::TwSetParam(
+      this->bar,
+      varName,
+      paramName,
+      paramValueType,
+      inValueCount,
+      inValues);
+}
+
+int igl::ReTwBar::TwGetParam(
+  const char *varName, 
+  const char *paramName, 
+  TwParamValueType paramValueType, 
+  unsigned int outValueMaxCount,
+  void *outValues)
+{
+  return 
+    ::TwGetParam(
+      this->bar,
+      varName,
+      paramName,
+      paramValueType,
+      outValueMaxCount,
+      outValues);
+}
+
+int igl::ReTwBar::TwRefreshBar()
+{
+  return ::TwRefreshBar(this->bar);
+}
+bool igl::ReTwBar::save(const char *file_name)
+{
+  FILE * fp;
+  if(file_name == NULL)
+  {
+    fp = stdout;
+  }else
+  {
+    fp = fopen(file_name,"w");
+  }
+
+  if(fp == NULL)
+  {
+    printf("ERROR: not able to open %s for writing...\n",file_name);
+    return false;
+  }
+
+  // Print all RW variables
+  for(
+    std::vector<ReTwRWItem>::iterator it = rw_items.begin(); 
+    it != rw_items.end(); 
+    it++)
+  {
+    const char * name = (*it).name;
+    TwType type = (*it).type;
+    void * var = (*it).var;
+    fprintf(fp,"%s: %s\n",
+      name,
+      get_value_as_string(var,type).c_str());
+  }
+
+  char var[MAX_CB_VAR_SIZE];
+  // Print all CB variables
+  for(
+    std::vector<ReTwCBItem>::iterator it = cb_items.begin(); 
+    it != cb_items.end(); 
+    it++)
+  {
+    const char * name = it->name;
+    TwType type = it->type;
+    //TwSetVarCallback setCallback = it->setCallback;
+    TwGetVarCallback getCallback = it->getCallback;
+    void * clientData = it->clientData;
+    // I'm not sure how to do what I want to do. getCallback needs to be sure
+    // that it can write to var. So var needs to point to a valid and big
+    // enough chunk of memory
+    getCallback(var,clientData);
+    fprintf(fp,"%s: %s\n",
+      name,
+      get_value_as_string(var,type).c_str());
+  }
+
+  fprintf(fp,"\n");
+
+  if(file_name != NULL)
+  {
+    fclose(fp);
+  }
+  // everything succeeded
+  return true;
+}
+
+std::string igl::ReTwBar::get_value_as_string(
+  void * var, 
+  TwType type)
+{
+  std::stringstream sstr;
+  switch(type)
+  {
+    case TW_TYPE_BOOLCPP:
+      {
+        sstr << "TW_TYPE_BOOLCPP" << " ";
+        sstr << *(static_cast<bool*>(var));
+        break;
+      }
+    case TW_TYPE_QUAT4F:
+      {
+        sstr << "TW_TYPE_QUAT4F" << " ";
+        // Q: Why does casting to float* work? shouldn't I have to cast to
+        // float**?
+        float * q = static_cast<float*>(var);
+        sstr << q[0] << " " << q[1] << " " << q[2] << " " << q[3];
+        break;
+      }
+    case TW_TYPE_COLOR4F:
+      {
+        sstr << "TW_TYPE_COLOR4F" << " ";
+        float * c = static_cast<float*>(var);
+        sstr << c[0] << " " << c[1] << " " << c[2] << " " << c[3];
+        break;
+      }
+    case TW_TYPE_COLOR3F:
+      {
+        sstr << "TW_TYPE_COLOR3F" << " ";
+        float * c = static_cast<float*>(var);
+        sstr << c[0] << " " << c[1] << " " << c[2];
+        break;
+      }
+    case TW_TYPE_DIR3F:
+      {
+        sstr << "TW_TYPE_DIR3F" << " ";
+        float * d = static_cast<float*>(var);
+        sstr << d[0] << " " << d[1] << " " << d[2];
+        break;
+      }
+    case TW_TYPE_BOOL32:
+      {
+        sstr << "TW_TYPE_BOOL32" << " ";
+        sstr << *(static_cast<int*>(var));
+        break;
+      }
+    case TW_TYPE_INT32:
+      {
+        sstr << "TW_TYPE_INT32" << " ";
+        sstr << *(static_cast<int*>(var));
+        break;
+      }
+    case TW_TYPE_FLOAT:
+      {
+        sstr << "TW_TYPE_FLOAT" << " ";
+        sstr << *(static_cast<float*>(var));
+        break;
+      }
+    case TW_TYPE_DOUBLE:
+      {
+        sstr << "TW_TYPE_DOUBLE" << " ";
+        sstr << *(static_cast<double*>(var));
+        break;
+      }
+    default:
+      {
+        std::map<TwType,std::pair<const char *,std::vector<TwEnumVal> > >::iterator iter = 
+          ReTw_custom_types.find(type);
+        if(iter != ReTw_custom_types.end())
+        {
+          sstr << (*iter).second.first << " ";
+          int enum_val = *(static_cast<int*>(var));
+          // try find display name for enum value
+          std::vector<TwEnumVal>::iterator eit = (*iter).second.second.begin();
+          bool found = false;
+          for(;eit<(*iter).second.second.end();eit++)
+          {
+            if(enum_val == eit->Value)
+            {
+              sstr << eit->Label;
+              found = true;
+              break;
+            }
+          }
+          if(!found)
+          {
+            sstr << "ERROR_ENUM_VALUE_NOT_DEFINED";
+          }
+        }else
+        {
+          sstr << "ERROR_TYPE_NOT_SUPPORTED";
+        }
+        break;
+      }
+  }
+  return sstr.str();
+}
+
+bool igl::ReTwBar::load(const char *file_name)
+{
+  FILE * fp;
+  fp = fopen(file_name,"r");
+
+  if(fp == NULL)
+  {
+    printf("ERROR: not able to open %s for reading...\n",file_name);
+    return false;
+  }
+
+  // go through file line by line
+  char line[MAX_LINE];
+  bool still_comments;
+  char name[MAX_WORD];
+  char type_str[MAX_WORD];
+  char value_str[MAX_WORD];
+
+
+  // line number
+  int j = 0;
+  bool finished = false;
+  while(true)
+  {
+    // Eat comments
+    still_comments = true;
+    while(still_comments)
+    {
+      if(fgets(line,MAX_LINE,fp) == NULL)
+      {
+        finished = true;
+        break;
+      }
+      // Blank lines and lines that begin with # are comments
+      still_comments = (line[0] == '#' || line[0] == '\n');
+      j++;
+    }
+    if(finished)
+    {
+      break;
+    }
+
+    sscanf(line,"%[^:]: %s %[^\n]",name,type_str,value_str);
+    //printf("%s: %s %s\n",name, type_str,value_str);
+
+    TwType type;
+    if(!type_from_string(type_str,type))
+    {
+      printf("ERROR: %s type not found... Skipping...\n",type_str);
+      continue;
+    }
+    set_value_from_string(name,type,value_str);
+
+  }
+
+  fclose(fp);
+  
+  // everything succeeded
+  return true;
+}
+
+bool igl::ReTwBar::type_from_string(const char *type_str, TwType & type)
+{
+  // first check default types
+  for(int j = 0; j < RETW_NUM_DEFAULT_TYPE_STRINGS; j++)
+  {
+    if(strcmp(type_str,ReTwDefaultTypeStrings[j].type_str) == 0)
+    {
+      type = ReTwDefaultTypeStrings[j].type;
+      return true;
+      break;
+    }
+  }
+
+  // then check custom types
+  std::map<TwType,std::pair<const char *,std::vector<TwEnumVal> > >::iterator iter = 
+    ReTw_custom_types.begin();
+  for(;iter != ReTw_custom_types.end(); iter++)
+  {
+    if(strcmp((*iter).second.first,type_str)==0)
+    {
+      type = (*iter).first;
+      return true;
+    }
+  }
+  return false;
+}
+
+bool igl::ReTwBar::set_value_from_string(
+  const char * name, 
+  TwType type, 
+  const char * value_str)
+{
+  void * value;
+  // possible value slots
+  int i;
+  float v;
+  double dv;
+  float f[4];
+  bool b;
+
+  // First try to get value from default types
+  switch(type)
+  {
+    case TW_TYPE_BOOLCPP:
+      {
+        int ib;
+        if(sscanf(value_str," %d",&ib) == 1)
+        {
+          b = ib!=0;
+          value = &b;
+        }else
+        {
+          printf("ERROR: Bad value format...\n");
+          return false;
+        }
+        break;
+      }
+    case TW_TYPE_QUAT4F:
+    case TW_TYPE_COLOR4F:
+      {
+        if(sscanf(value_str," %f %f %f %f",&f[0],&f[1],&f[2],&f[3]) == 4)
+        {
+          value = &f;
+        }else
+        {
+          printf("ERROR: Bad value format...\n");
+          return false;
+        }
+        break;
+      }
+    case TW_TYPE_COLOR3F:
+    case TW_TYPE_DIR3F:
+      {
+        if(sscanf(value_str," %f %f %f",&f[0],&f[1],&f[2]) == 3)
+        {
+          value = &f;
+        }else
+        {
+          printf("ERROR: Bad value format...\n");
+          return false;
+        }
+        break;
+      }
+    case TW_TYPE_BOOL32:
+    case TW_TYPE_INT32:
+      {
+        if(sscanf(value_str," %d",&i) == 1)
+        {
+          value = &i;
+        }else
+        {
+          printf("ERROR: Bad value format...\n");
+          return false;
+        }
+        break;
+      }
+    case TW_TYPE_FLOAT:
+      {
+        if(sscanf(value_str," %f",&v) == 1)
+        {
+          value = &v;
+        }else
+        {
+          printf("ERROR: Bad value format...\n");
+          return false;
+        }
+        break;
+      }
+    case TW_TYPE_DOUBLE:
+      {
+        if(sscanf(value_str," %lf",&dv) == 1)
+        {
+          value = &dv;
+        }else
+        {
+          printf("ERROR: Bad value format...\n");
+          return false;
+        }
+        break;
+      }
+    default:
+      // Try to find type in custom enum types
+      std::map<TwType,std::pair<const char *,std::vector<TwEnumVal> > >::iterator iter = 
+        ReTw_custom_types.find(type);
+      if(iter != ReTw_custom_types.end())
+      {
+        std::vector<TwEnumVal>::iterator eit = (*iter).second.second.begin();
+        bool found = false;
+        for(;eit<(*iter).second.second.end();eit++)
+        {
+          if(strcmp(value_str,eit->Label) == 0)
+          {
+            i = eit->Value;
+            value = &i;
+            found = true;
+            break;
+          }
+        }
+        if(!found)
+        {
+          printf("ERROR_ENUM_VALUE_NOT_DEFINED");
+        }
+      }else
+      {
+        printf("ERROR_TYPE_NOT_SUPPORTED\n");
+      }
+
+      break;
+  }
+
+
+  // Find variable based on name
+  // First look in RW items
+  bool item_found = false;
+  for(
+    std::vector<ReTwRWItem>::iterator it = rw_items.begin(); 
+    it != rw_items.end(); 
+    it++)
+  {
+    if(strcmp(it->name,name) == 0)
+    {
+      void * var = it->var;
+      switch(type)
+      {
+        case TW_TYPE_BOOLCPP:
+          {
+            bool * bvar = static_cast<bool*>(var);
+            bool * bvalue = static_cast<bool*>(value);
+            *bvar = *bvalue;
+            break;
+          }
+        case TW_TYPE_QUAT4F:
+        case TW_TYPE_COLOR4F:
+          {
+            float * fvar = static_cast<float*>(var);
+            float * fvalue = static_cast<float*>(value);
+            fvar[0] = fvalue[0];
+            fvar[1] = fvalue[1];
+            fvar[2] = fvalue[2];
+            fvar[3] = fvalue[3];
+            break;
+          }
+        case TW_TYPE_COLOR3F:
+        case TW_TYPE_DIR3F:
+          {
+            float * fvar = static_cast<float*>(var);
+            float * fvalue = static_cast<float*>(value);
+            fvar[0] = fvalue[0];
+            fvar[1] = fvalue[1];
+            fvar[2] = fvalue[2];
+            break;
+          }
+        case TW_TYPE_BOOL32:
+        case TW_TYPE_INT32:
+          {
+            int * ivar = static_cast<int*>(var);
+            int * ivalue = static_cast<int*>(value);
+            *ivar = *ivalue;
+            break;
+          }
+        case TW_TYPE_FLOAT:
+          {
+            float * fvar = static_cast<float*>(var);
+            float * fvalue = static_cast<float*>(value);
+            *fvar = *fvalue;
+            break;
+          }
+        case TW_TYPE_DOUBLE:
+          {
+            double * dvar =   static_cast<double*>(var);
+            double * fvalue = static_cast<double*>(value);
+            *dvar = *fvalue;
+            break;
+          }
+        default:
+          // Try to find type in custom enum types
+          std::map<TwType,std::pair<const char *,std::vector<TwEnumVal> > >::iterator iter = 
+            ReTw_custom_types.find(type);
+          if(iter != ReTw_custom_types.end())
+          {
+            int * ivar = static_cast<int*>(var);
+            std::vector<TwEnumVal>::iterator eit = (*iter).second.second.begin();
+            bool found = false;
+            for(;eit<(*iter).second.second.end();eit++)
+            {
+              if(strcmp(value_str,eit->Label) == 0)
+              {
+                *ivar = eit->Value;
+                found = true;
+                break;
+              }
+            }
+            if(!found)
+            {
+              printf("ERROR_ENUM_VALUE_NOT_DEFINED");
+            }
+          }else
+          {
+            printf("ERROR_TYPE_NOT_SUPPORTED\n");
+          }
+          break;
+      }
+      item_found = true;
+      break;
+    }
+  }
+
+  // Try looking in CB items
+  if(!item_found)
+  {
+    for(
+      std::vector<ReTwCBItem>::iterator it = cb_items.begin(); 
+      it != cb_items.end(); 
+      it++)
+    {
+      if(strcmp(it->name,name) == 0)
+      {
+        it->setCallback(value,it->clientData);
+        item_found = true;
+        break;
+      }
+    }
+  }
+
+  if(!item_found)
+  {
+    printf("ERROR: item not found\n");
+  }
+  return true;
+}

+ 11 - 0
ZERO.h

@@ -0,0 +1,11 @@
+// Often one needs a reference to a dummy variable containing zero as its
+// value, for example when using AntTweakBar's
+// TwSetParam( "3D View", "opened", TW_PARAM_INT32, 1, &TW_ZERO);
+namespace igl
+{
+  const char CHAR_ZERO = 0;
+  const int INT_ZERO = 0;
+  const unsigned int UNSIGNED_INT_ZERO = 0;
+  const double DOUBLE_ZERO = 0;
+  const float FLOAT_ZERO = 0;
+}

+ 30 - 0
examples/ReAntTweakBar/Makefile

@@ -0,0 +1,30 @@
+
+.PHONY: all
+
+all: example
+
+.PHONY: example
+
+STATIC_ANTTWEAKBAR=""
+
+igl_lib=../../
+
+ifdef STATIC_ANTTWEAKBAR
+CFLAGS=-g -DSTATIC_ANTTWEAKBAR
+inc=-I$(igl_lib) -I./static
+lib=-Lstatic -lAntTweakBar -framework AppKit
+else
+CFLAGS=-g
+inc=-I$(igl_lib)
+lib=-lAntTweakBar
+endif
+
+example: example.o
+	g++ $(CFLAGS) -o example example.o -framework OpenGL -framework GLUT $(lib)
+	rm example.o
+
+example.o: example.cpp
+	g++ $(CFLAGS) -c example.cpp -o example.o $(inc)
+clean:
+	rm -f example.o
+	rm -f example

+ 29 - 0
examples/ReAntTweakBar/README

@@ -0,0 +1,29 @@
+ReAntTweakBar is a minimal wrapper for the AntTweakBar library that allows
+"bars" to be saved and load from disk. Changing your existing app that users
+AntTweakBar to use ReAntTweakBar is trivial.
+
+This directory should contain:
+  README
+  example.cpp
+  example  (option example binary)
+  temp.rbr (optional example ReAntTweakBar output)
+
+Many (but not all) variable types are supported. I'll try to keep track them
+here:
+  TW_TYPE_BOOLCPP
+  TW_TYPE_QUAT4F
+  TW_TYPE_COLOR4F
+  TW_TYPE_COLOR3F
+  TW_TYPE_DIR3F
+  TW_TYPE_BOOL32
+  TW_TYPE_INT32
+  TW_TYPE_FLOAT
+  TW_TYPE_DOUBLE
+  and
+  custom TwTypes made with TwDefineEnum
+
+I'm working on adding the rest on an as-needed basis. Adding a new type only
+requires changes in a few places...
+
+Look in example.cpp for an example of how to compile with ReAntTweakBar and use
+it.

+ 380 - 0
examples/ReAntTweakBar/example.cpp

@@ -0,0 +1,380 @@
+/*
+  This is an example program that came with AntTweakBar modified to use ReAntTweakBar
+
+  On mac os x compile with:
+
+  g++ -c ReAntTweakBar.cpp -o ReAntTweakBar.o 
+  g++ -c example.cpp -o example.o 
+  g++ -o example ReAntTweakBar.o example.o -framework OpenGL -framework GLUT -lAntTweakBar
+  rm *.o
+
+*/
+
+#ifdef __APPLE__
+#define _MACOSX
+#endif
+// ORIGINAL COPYRIGHT INFO
+//  ---------------------------------------------------------------------------
+//
+//  @file       TwSimpleGLUT.c
+//  @brief      A simple example that uses AntTweakBar with OpenGL and GLUT.
+//
+//              AntTweakBar: http://www.antisphere.com/Wiki/tools:anttweakbar
+//              OpenGL:      http://www.opengl.org
+//              GLUT:        http://opengl.org/resources/libraries/glut
+//  
+//  @author     Philippe Decaudin - http://www.antisphere.com
+//  @date       2006/05/20
+//
+//  Compilation:
+//  http://www.antisphere.com/Wiki/tools:anttweakbar:examples#twsimpleglut
+//
+//  ---------------------------------------------------------------------------
+
+
+#include "ReAntTweakBar.h"
+using namespace igl;
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <math.h>
+
+#if defined(_WIN32) || defined(_WIN64)
+//  MiniGLUT.h is provided to avoid the need of having GLUT installed to 
+//  recompile this example. Do not use it in your own programs, better
+//  install and use the actual GLUT library SDK.
+#   define USE_MINI_GLUT
+#endif
+
+#if defined(USE_MINI_GLUT)
+#   include "../src/MiniGLUT.h"
+#elif defined(_MACOSX)
+#   include <GLUT/glut.h>
+#else
+#   include <GL/glut.h>
+#endif
+
+#define REBAR_NAME "temp.rbr"
+
+
+// This example displays one of the following shapes
+typedef enum { SHAPE_TEAPOT=1, SHAPE_TORUS, SHAPE_CONE } Shape;
+#define NUM_SHAPES 3
+Shape g_CurrentShape = SHAPE_TORUS;
+// Shapes scale
+float g_Zoom = 1.0f;
+// Shape orientation (stored as a quaternion)
+float g_Rotation[] = { 0.0f, 0.0f, 0.0f, 1.0f };
+// Auto rotate
+int g_AutoRotate = 0;
+int g_RotateTime = 0;
+float g_RotateStart[] = { 0.0f, 0.0f, 0.0f, 1.0f };
+// Shapes material
+float g_MatAmbient[] = { 0.5f, 0.0f, 0.0f, 1.0f };
+float g_MatDiffuse[] = { 1.0f, 1.0f, 0.0f, 1.0f };
+// Light parameter
+double g_LightMultiplier = 1.0f;
+float g_LightDirection[] = { -0.57735f, -0.57735f, -0.57735f };
+
+ReTwBar rebar; // Pointer to the tweak bar
+
+// Routine to set a quaternion from a rotation axis and angle
+// ( input axis = float[3] angle = float  output: quat = float[4] )
+void SetQuaternionFromAxisAngle(const float *axis, float angle, float *quat)
+{
+  float sina2, norm;
+  sina2 = (float)sin(0.5f * angle);
+  norm = (float)sqrt(axis[0]*axis[0] + axis[1]*axis[1] + axis[2]*axis[2]);
+  quat[0] = sina2 * axis[0] / norm;
+  quat[1] = sina2 * axis[1] / norm;
+  quat[2] = sina2 * axis[2] / norm;
+  quat[3] = (float)cos(0.5f * angle);
+  
+}
+
+
+// Routine to convert a quaternion to a 4x4 matrix
+// ( input: quat = float[4]  output: mat = float[4*4] )
+void ConvertQuaternionToMatrix(const float *quat, float *mat)
+{
+  float yy2 = 2.0f * quat[1] * quat[1];
+  float xy2 = 2.0f * quat[0] * quat[1];
+  float xz2 = 2.0f * quat[0] * quat[2];
+  float yz2 = 2.0f * quat[1] * quat[2];
+  float zz2 = 2.0f * quat[2] * quat[2];
+  float wz2 = 2.0f * quat[3] * quat[2];
+  float wy2 = 2.0f * quat[3] * quat[1];
+  float wx2 = 2.0f * quat[3] * quat[0];
+  float xx2 = 2.0f * quat[0] * quat[0];
+  mat[0*4+0] = - yy2 - zz2 + 1.0f;
+  mat[0*4+1] = xy2 + wz2;
+  mat[0*4+2] = xz2 - wy2;
+  mat[0*4+3] = 0;
+  mat[1*4+0] = xy2 - wz2;
+  mat[1*4+1] = - xx2 - zz2 + 1.0f;
+  mat[1*4+2] = yz2 + wx2;
+  mat[1*4+3] = 0;
+  mat[2*4+0] = xz2 + wy2;
+  mat[2*4+1] = yz2 - wx2;
+  mat[2*4+2] = - xx2 - yy2 + 1.0f;
+  mat[2*4+3] = 0;
+  mat[3*4+0] = mat[3*4+1] = mat[3*4+2] = 0;
+  mat[3*4+3] = 1;
+}
+
+
+// Routine to multiply 2 quaternions (ie, compose rotations)
+// ( input q1 = float[4] q2 = float[4]  output: qout = float[4] )
+void MultiplyQuaternions(const float *q1, const float *q2, float *qout)
+{
+  float qr[4];
+	qr[0] = q1[3]*q2[0] + q1[0]*q2[3] + q1[1]*q2[2] - q1[2]*q2[1];
+	qr[1] = q1[3]*q2[1] + q1[1]*q2[3] + q1[2]*q2[0] - q1[0]*q2[2];
+	qr[2] = q1[3]*q2[2] + q1[2]*q2[3] + q1[0]*q2[1] - q1[1]*q2[0];
+	qr[3]  = q1[3]*q2[3] - (q1[0]*q2[0] + q1[1]*q2[1] + q1[2]*q2[2]);
+  qout[0] = qr[0]; qout[1] = qr[1]; qout[2] = qr[2]; qout[3] = qr[3];
+}
+
+
+// Callback function called by GLUT to render screen
+void Display(void)
+{
+  float v[4]; // will be used to set light paramters
+  float mat[4*4]; // rotation matrix
+  
+  // Clear frame buffer
+  glClearColor(0, 0, 0, 1);
+  glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+  
+  glEnable(GL_DEPTH_TEST);
+  glDisable(GL_CULL_FACE);
+  glEnable(GL_NORMALIZE);
+  
+  // Set light
+  glEnable(GL_LIGHTING);
+  glEnable(GL_LIGHT0);
+  v[0] = v[1] = v[2] = g_LightMultiplier*0.4f; v[3] = 1.0f;
+  glLightfv(GL_LIGHT0, GL_AMBIENT, v);
+  v[0] = v[1] = v[2] = g_LightMultiplier*0.8f; v[3] = 1.0f;
+  glLightfv(GL_LIGHT0, GL_DIFFUSE, v);
+  v[0] = -g_LightDirection[0]; v[1] = -g_LightDirection[1]; v[2] = -g_LightDirection[2]; v[3] = 0.0f;
+  glLightfv(GL_LIGHT0, GL_POSITION, v);
+  
+  // Set material
+  glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, g_MatAmbient);
+  glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, g_MatDiffuse);
+  
+  // Rotate and draw shape
+  glPushMatrix();
+  glTranslatef(0.5f, -0.3f, 0.0f);
+  if( g_AutoRotate ) 
+  {
+    float axis[3] = { 0, 1, 0 };
+    float angle = (float)(glutGet(GLUT_ELAPSED_TIME)-g_RotateTime)/1000.0f;
+    float quat[4];
+    SetQuaternionFromAxisAngle(axis, angle, quat);
+    MultiplyQuaternions(g_RotateStart, quat, g_Rotation);
+  }
+  ConvertQuaternionToMatrix(g_Rotation, mat);
+  glMultMatrixf(mat);
+  glScalef(g_Zoom, g_Zoom, g_Zoom);
+  glCallList(g_CurrentShape);
+  glPopMatrix();
+  
+  // Draw tweak bars
+  TwDraw();
+  
+  // Present frame buffer
+  glutSwapBuffers();
+  
+  // Recall Display at next frame
+  glutPostRedisplay();
+}
+
+
+// Callback function called by GLUT when window size changes
+void Reshape(int width, int height)
+{
+  // Set OpenGL viewport and camera
+  glViewport(0, 0, width, height);
+  glMatrixMode(GL_PROJECTION);
+  glLoadIdentity();
+  gluPerspective(40, (double)width/height, 1, 10);
+  glMatrixMode(GL_MODELVIEW);
+  glLoadIdentity();
+  gluLookAt(0,0,5, 0,0,0, 0,1,0);
+  glTranslatef(0, 0.6f, -1);
+  
+  // Send the new window size to AntTweakBar
+  TwWindowSize(width, height);
+}
+
+
+// Function called at exit
+void Terminate(void)
+{ 
+  rebar.save(REBAR_NAME);
+
+  glDeleteLists(SHAPE_TEAPOT, NUM_SHAPES);
+  
+  TwTerminate();
+}
+
+
+//  Callback function called when the 'AutoRotate' variable value of the tweak bar has changed
+void TW_CALL SetAutoRotateCB(const void *value, void *clientData)
+{
+  (void)clientData; // unused
+  
+  g_AutoRotate = *(const int *)(value); // copy value to g_AutoRotate
+  if( g_AutoRotate!=0 ) 
+  {
+    // init rotation
+    g_RotateTime = glutGet(GLUT_ELAPSED_TIME);
+    g_RotateStart[0] = g_Rotation[0];
+    g_RotateStart[1] = g_Rotation[1];
+    g_RotateStart[2] = g_Rotation[2];
+    g_RotateStart[3] = g_Rotation[3];
+    
+    // make Rotation variable read-only
+    TwDefine(" TweakBar/ObjRotation readonly ");
+  }
+  else
+    // make Rotation variable read-write
+    TwDefine(" TweakBar/ObjRotation readwrite ");
+}
+
+
+//  Callback function called by the tweak bar to get the 'AutoRotate' value
+void TW_CALL GetAutoRotateCB(void *value, void *clientData)
+{
+  (void)clientData; // unused
+  *(int *)(value) = g_AutoRotate; // copy g_AutoRotate to value
+}
+
+
+// Main
+int main(int argc, char *argv[])
+{
+  float axis[] = { 0.7f, 0.7f, 0.0f }; // initial model rotation
+  float angle = 0.8f;
+  
+  // Initialize AntTweakBar
+  // (note that AntTweakBar could also be intialized after GLUT, no matter)
+  if( !TwInit(TW_OPENGL, NULL) )
+  {
+    // A fatal error occured    
+    fprintf(stderr, "AntTweakBar initialization failed: %s\n", TwGetLastError());
+    return 1;
+  }
+  
+  // Initialize GLUT
+  glutInit(&argc, argv);
+  glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);
+  glutInitWindowSize(640, 480);
+  glutCreateWindow("AntTweakBar simple example using GLUT");
+  glutCreateMenu(NULL);
+  
+  // Set GLUT callbacks
+  glutDisplayFunc(Display);
+  glutReshapeFunc(Reshape);
+  atexit(Terminate);  // Called after glutMainLoop ends
+  
+  // Set GLUT event callbacks
+  // - Directly redirect GLUT mouse button events to AntTweakBar
+  glutMouseFunc((GLUTmousebuttonfun)TwEventMouseButtonGLUT);
+  // - Directly redirect GLUT mouse motion events to AntTweakBar
+  glutMotionFunc((GLUTmousemotionfun)TwEventMouseMotionGLUT);
+  // - Directly redirect GLUT mouse "passive" motion events to AntTweakBar (same as MouseMotion)
+  glutPassiveMotionFunc((GLUTmousemotionfun)TwEventMouseMotionGLUT);
+  // - Directly redirect GLUT key events to AntTweakBar
+  glutKeyboardFunc((GLUTkeyboardfun)TwEventKeyboardGLUT);
+  // - Directly redirect GLUT special key events to AntTweakBar
+  glutSpecialFunc((GLUTspecialfun)TwEventSpecialGLUT);
+  // - Send 'glutGetModifers' function pointer to AntTweakBar;
+  //   required because the GLUT key event functions do not report key modifiers states.
+  TwGLUTModifiersFunc(glutGetModifiers);
+  
+  // Create some 3D objects (stored in display lists)
+  glNewList(SHAPE_TEAPOT, GL_COMPILE);
+  glutSolidTeapot(1.0);
+  glEndList();
+  glNewList(SHAPE_TORUS, GL_COMPILE);
+  glutSolidTorus(0.3, 1.0, 16, 32);
+  glEndList();
+  glNewList(SHAPE_CONE, GL_COMPILE);
+  glutSolidCone(1.0, 1.5, 64, 4);
+  glEndList();
+  
+  // Create a tweak bar
+  rebar.TwNewBar("TweakBar");
+  TwDefine(" GLOBAL help='This example shows how to integrate AntTweakBar with GLUT and OpenGL.' "); // Message added to the help bar.
+  TwDefine(" TweakBar size='200 400' color='96 216 224' "); // change default tweak bar size and color
+  
+  // Add 'g_Zoom' to 'bar': this is a modifable (RW) variable of type TW_TYPE_FLOAT. Its key shortcuts are [z] and [Z].
+  rebar.TwAddVarRW("Zoom", TW_TYPE_FLOAT, &g_Zoom, 
+             " min=0.01 max=2.5 step=0.01 keyIncr=z keyDecr=Z help='Scale the object (1=original size).' ");
+  
+  // Add 'g_Rotation' to 'bar': this is a variable of type TW_TYPE_QUAT4F which defines the object's orientation
+  rebar.TwAddVarRW("ObjRotation", TW_TYPE_QUAT4F, &g_Rotation, 
+             " label='Object rotation' open help='Change the object orientation.' ");
+  
+  // Add callback to toggle auto-rotate mode (callback functions are defined above).
+  rebar.TwAddVarCB("AutoRotate", TW_TYPE_BOOL32, SetAutoRotateCB, GetAutoRotateCB, NULL, 
+             " label='Auto-rotate' key=space help='Toggle auto-rotate mode.' ");
+  
+  // Add 'g_LightMultiplier' to 'bar': this is a variable of type TW_TYPE_FLOAT. Its key shortcuts are [+] and [-].
+  rebar.TwAddVarRW("Multiplier", TW_TYPE_DOUBLE, &g_LightMultiplier, 
+             " label='Light booster' min=0.1 max=4 step=0.02 keyIncr='+' keyDecr='-' help='Increase/decrease the light power.' ");
+  
+  // Add 'g_LightDirection' to 'bar': this is a variable of type TW_TYPE_DIR3F which defines the light direction
+  rebar.TwAddVarRW("Light Dir", TW_TYPE_DIR3F, &g_LightDirection, 
+             " label='Light direction' open help='Change the light direction.' ");
+  
+  // Add 'g_MatAmbient' to 'bar': this is a variable of type TW_TYPE_COLOR3F (3 floats color, alpha is ignored)
+  // and is inserted into a group named 'Material'.
+  rebar.TwAddVarRW("Ambient", TW_TYPE_COLOR3F, &g_MatAmbient, " group='Material' ");
+  
+  // Add 'g_MatDiffuse' to 'bar': this is a variable of type TW_TYPE_COLOR3F (3 floats color, alpha is ignored)
+  // and is inserted into group 'Material'.
+  rebar.TwAddVarRW("Diffuse", TW_TYPE_COLOR3F, &g_MatDiffuse, " group='Material' ");
+  
+  // Add the enum variable 'g_CurrentShape' to 'bar'
+  // (before adding an enum variable, its enum type must be declared to AntTweakBar as follow)
+  {
+    // ShapeEV associates Shape enum values with labels that will be displayed instead of enum values
+    TwEnumVal shapeEV[NUM_SHAPES] = { {SHAPE_TEAPOT, "Teapot"}, {SHAPE_TORUS, "Torus"}, {SHAPE_CONE, "Cone"} };
+    // Create a type for the enum shapeEV
+    TwType shapeType = ReTwDefineEnum("ShapeType", shapeEV, NUM_SHAPES);
+    // add 'g_CurrentShape' to 'bar': this is a variable of type ShapeType. Its key shortcuts are [<] and [>].
+    rebar.TwAddVarRW("Shape", shapeType, &g_CurrentShape, " keyIncr='<' keyDecr='>' help='Change object shape.' ");
+  }
+  
+  // Store time
+  g_RotateTime = glutGet(GLUT_ELAPSED_TIME);
+  // Init rotation
+  SetQuaternionFromAxisAngle(axis, angle, g_Rotation);
+  SetQuaternionFromAxisAngle(axis, angle, g_RotateStart);
+
+  FILE * fp = fopen(REBAR_NAME,"r");
+  if(fp != NULL)
+  {
+    fclose(fp);
+    if(rebar.load(REBAR_NAME))
+    {
+      printf("ReAntTweakBar reloaded successfully from %s.\n",REBAR_NAME);
+    }else
+    {
+      printf("ReAntTweakBar failed to load from %s.\n",REBAR_NAME);
+    }
+  }else
+  {
+    printf("%s ReAntTweakBar file does not exist (yet).\n",REBAR_NAME);
+  }
+  
+  // Call the GLUT main loop
+  glutMainLoop();
+  
+  return 0;
+}
+

+ 324 - 0
examples/ReAntTweakBar/static/AntTweakBar.h

@@ -0,0 +1,324 @@
+// ----------------------------------------------------------------------------
+//
+//  @file       AntTweakBar.h
+//
+//  @brief      AntTweakBar is a light and intuitive graphical user interface 
+//              that can be readily integrated into OpenGL and DirectX 
+//              applications in order to interactively tweak them.
+//
+//  @author     Philippe Decaudin - http://www.antisphere.com
+//  @date       2005/09/20
+//
+//  @doc        http://www.antisphere.com/Wiki/tools:anttweakbar
+//
+//  @license    This file is part of the AntTweakBar library.
+//              AntTweakBar is a free software released under the zlib license.
+//              For conditions of distribution and use, see License.txt
+//
+// ----------------------------------------------------------------------------
+
+
+#if !defined TW_INCLUDED
+#define TW_INCLUDED
+
+#include <stddef.h>
+
+#define TW_VERSION  113 // Version Mmm : M=Major mm=minor (e.g., 102 is version 1.02)
+
+
+#ifdef  __cplusplus
+#   if defined(_MSC_VER)
+#       pragma warning(push)
+#       pragma warning(disable: 4995 4530)
+#       include <string>
+#       pragma warning(pop)
+#   else
+#       include <string>
+#   endif
+    extern "C" {
+#endif  // __cplusplus
+
+
+// ----------------------------------------------------------------------------
+//  OS specific definitions
+// ----------------------------------------------------------------------------
+
+#if defined(_WIN32) || defined(_WIN64)
+#   define TW_CALL          __stdcall
+#   define TW_EXPORT_API    __declspec(dllexport)
+#   define TW_IMPORT_API    __declspec(dllimport)
+#else
+#   define TW_CALL
+#   define TW_EXPORT_API
+#   define TW_IMPORT_API
+#endif
+
+#if defined TW_EXPORTS
+#   define TW_API   TW_EXPORT_API
+#elif defined TW_STATIC
+#   define TW_API
+#   if defined(_MSC_VER) && !defined(TW_NO_LIB_PRAGMA)
+#       pragma comment(lib, "AntTweakBarStatic")
+#   endif
+#else
+#   define TW_API   TW_IMPORT_API
+#   if defined(_MSC_VER) && !defined(TW_NO_LIB_PRAGMA)
+#       pragma comment(lib, "AntTweakBar")
+#   endif
+#endif
+
+
+// ----------------------------------------------------------------------------
+//  Bar functions and definitions
+// ----------------------------------------------------------------------------
+
+typedef struct CTwBar TwBar; // structure CTwBar is not exposed.
+
+TW_API TwBar *      TW_CALL TwNewBar(const char *barName);
+TW_API int          TW_CALL TwDeleteBar(TwBar *bar);
+TW_API int          TW_CALL TwDeleteAllBars();
+TW_API int          TW_CALL TwSetTopBar(const TwBar *bar);
+TW_API TwBar *      TW_CALL TwGetTopBar();
+TW_API int          TW_CALL TwSetBottomBar(const TwBar *bar);
+TW_API TwBar *      TW_CALL TwGetBottomBar();
+TW_API const char * TW_CALL TwGetBarName(TwBar *bar);
+TW_API int          TW_CALL TwGetBarCount();
+TW_API TwBar *      TW_CALL TwGetBarByIndex(int barIndex);
+TW_API TwBar *      TW_CALL TwGetBarByName(const char *barName);
+TW_API int          TW_CALL TwRefreshBar(TwBar *bar);
+
+
+// ----------------------------------------------------------------------------
+//  Var functions and definitions
+// ----------------------------------------------------------------------------
+
+typedef enum ETwType
+{
+    TW_TYPE_UNDEF   = 0,
+#ifdef __cplusplus
+    TW_TYPE_BOOLCPP = 1,
+#endif // __cplusplus
+    TW_TYPE_BOOL8   = 2,
+    TW_TYPE_BOOL16,
+    TW_TYPE_BOOL32,
+    TW_TYPE_CHAR,
+    TW_TYPE_INT8,
+    TW_TYPE_UINT8,
+    TW_TYPE_INT16,
+    TW_TYPE_UINT16,
+    TW_TYPE_INT32,
+    TW_TYPE_UINT32,
+    TW_TYPE_FLOAT,
+    TW_TYPE_DOUBLE,
+    TW_TYPE_COLOR32,    // 32 bits color. Order is RGBA if API is OpenGL or Direct3D10, and inversed if API is Direct3D9 (can be modified by defining 'colorOrder=...', see doc)
+    TW_TYPE_COLOR3F,    // 3 floats color. Order is RGB.
+    TW_TYPE_COLOR4F,    // 4 floats color. Order is RGBA.
+    TW_TYPE_CDSTRING,   // Null-terminated C Dynamic String (pointer to an array of char dynamically allocated with malloc/realloc/strdup)
+#ifdef __cplusplus
+    TW_TYPE_STDSTRING = (0x2fff0000+sizeof(std::string)),  // C++ STL string (std::string)
+#endif // __cplusplus
+    TW_TYPE_QUAT4F = TW_TYPE_CDSTRING+2, // 4 floats encoding a quaternion {qx,qy,qz,qs}
+    TW_TYPE_QUAT4D,     // 4 doubles encoding a quaternion {qx,qy,qz,qs}
+    TW_TYPE_DIR3F,      // direction vector represented by 3 floats
+    TW_TYPE_DIR3D       // direction vector represented by 3 doubles
+} TwType;
+#define TW_TYPE_CSSTRING(n) ((TwType)(0x30000000+((n)&0xfffffff))) // Null-terminated C Static String of size n (defined as char[n], with n<2^28)
+
+typedef void (TW_CALL * TwSetVarCallback)(const void *value, void *clientData);
+typedef void (TW_CALL * TwGetVarCallback)(void *value, void *clientData);
+typedef void (TW_CALL * TwButtonCallback)(void *clientData);
+
+TW_API int      TW_CALL TwAddVarRW(TwBar *bar, const char *name, TwType type, void *var, const char *def);
+TW_API int      TW_CALL TwAddVarRO(TwBar *bar, const char *name, TwType type, const void *var, const char *def);
+TW_API int      TW_CALL TwAddVarCB(TwBar *bar, const char *name, TwType type, TwSetVarCallback setCallback, TwGetVarCallback getCallback, void *clientData, const char *def);
+TW_API int      TW_CALL TwAddButton(TwBar *bar, const char *name, TwButtonCallback callback, void *clientData, const char *def);
+TW_API int      TW_CALL TwAddSeparator(TwBar *bar, const char *name, const char *def);
+TW_API int      TW_CALL TwRemoveVar(TwBar *bar, const char *name);
+TW_API int      TW_CALL TwRemoveAllVars(TwBar *bar);
+
+typedef struct CTwEnumVal
+{
+    int           Value;
+    const char *  Label;
+} TwEnumVal;
+typedef struct CTwStructMember
+{
+    const char *  Name;
+    TwType        Type;
+    size_t        Offset;
+    const char *  DefString;
+} TwStructMember;
+typedef void (TW_CALL * TwSummaryCallback)(char *summaryString, size_t summaryMaxLength, const void *value, void *clientData);
+
+TW_API int      TW_CALL TwDefine(const char *def);
+TW_API TwType   TW_CALL TwDefineEnum(const char *name, const TwEnumVal *enumValues, unsigned int nbValues);
+TW_API TwType   TW_CALL TwDefineStruct(const char *name, const TwStructMember *structMembers, unsigned int nbMembers, size_t structSize, TwSummaryCallback summaryCallback, void *summaryClientData);
+
+typedef void (TW_CALL * TwCopyCDStringToClient)(char **destinationClientStringPtr, const char *sourceString);
+TW_API void     TW_CALL TwCopyCDStringToClientFunc(TwCopyCDStringToClient copyCDStringFunc);
+TW_API void     TW_CALL TwCopyCDStringToLibrary(char **destinationLibraryStringPtr, const char *sourceClientString);
+#ifdef __cplusplus
+typedef void (TW_CALL * TwCopyStdStringToClient)(std::string& destinationClientString, const std::string& sourceString);
+TW_API void     TW_CALL TwCopyStdStringToClientFunc(TwCopyStdStringToClient copyStdStringToClientFunc);
+TW_API void     TW_CALL TwCopyStdStringToLibrary(std::string& destinationLibraryString, const std::string& sourceClientString);
+#endif // __cplusplus
+
+typedef enum ETwParamValueType
+{
+    TW_PARAM_INT32,
+    TW_PARAM_FLOAT,
+    TW_PARAM_DOUBLE,
+    TW_PARAM_CSTRING // Null-terminated array of char (ie, c-string)
+} TwParamValueType;
+TW_API int      TW_CALL TwGetParam(TwBar *bar, const char *varName, const char *paramName, TwParamValueType paramValueType, unsigned int outValueMaxCount, void *outValues);
+TW_API int      TW_CALL TwSetParam(TwBar *bar, const char *varName, const char *paramName, TwParamValueType paramValueType, unsigned int inValueCount, const void *inValues);
+
+
+// ----------------------------------------------------------------------------
+//  Managment functions and definitions
+// ----------------------------------------------------------------------------
+
+typedef enum ETwGraphAPI
+{
+    TW_OPENGL           = 1,
+    TW_DIRECT3D9        = 2,
+    TW_DIRECT3D10       = 3
+} TwGraphAPI;
+
+TW_API int      TW_CALL TwInit(TwGraphAPI graphAPI, void *device);
+TW_API int      TW_CALL TwTerminate();
+
+TW_API int      TW_CALL TwDraw();
+TW_API int      TW_CALL TwWindowSize(int width, int height);
+
+typedef enum ETwKeyModifier
+{
+    TW_KMOD_NONE        = 0x0000,   // same codes as SDL keysym.mod
+    TW_KMOD_SHIFT       = 0x0003,
+    TW_KMOD_CTRL        = 0x00c0,
+    TW_KMOD_ALT         = 0x0100,
+    TW_KMOD_META        = 0x0c00
+} TwKeyModifier;
+typedef enum EKeySpecial
+{
+    TW_KEY_BACKSPACE    = '\b',
+    TW_KEY_TAB          = '\t',
+    TW_KEY_CLEAR        = 0x0c,
+    TW_KEY_RETURN       = '\r',
+    TW_KEY_PAUSE        = 0x13,
+    TW_KEY_ESCAPE       = 0x1b,
+    TW_KEY_SPACE        = ' ',
+    TW_KEY_DELETE       = 0x7f,
+    TW_KEY_UP           = 273,      // same codes and order as SDL keysym.sym
+    TW_KEY_DOWN,
+    TW_KEY_RIGHT,
+    TW_KEY_LEFT,
+    TW_KEY_INSERT,
+    TW_KEY_HOME,
+    TW_KEY_END,
+    TW_KEY_PAGE_UP,
+    TW_KEY_PAGE_DOWN,
+    TW_KEY_F1,
+    TW_KEY_F2,
+    TW_KEY_F3,
+    TW_KEY_F4,
+    TW_KEY_F5,
+    TW_KEY_F6,
+    TW_KEY_F7,
+    TW_KEY_F8,
+    TW_KEY_F9,
+    TW_KEY_F10,
+    TW_KEY_F11,
+    TW_KEY_F12,
+    TW_KEY_F13,
+    TW_KEY_F14,
+    TW_KEY_F15,
+    TW_KEY_LAST
+} TwKeySpecial;
+
+TW_API int      TW_CALL TwKeyPressed(int key, int modifiers);
+
+typedef enum ETwMouseAction
+{
+    TW_MOUSE_RELEASED,
+    TW_MOUSE_PRESSED  
+} TwMouseAction;
+typedef enum ETwMouseButtonID
+{
+    TW_MOUSE_LEFT       = 1,    // same code as SDL_BUTTON_LEFT
+    TW_MOUSE_MIDDLE     = 2,    // same code as SDL_BUTTON_MIDDLE
+    TW_MOUSE_RIGHT      = 3     // same code as SDL_BUTTON_RIGHT
+} TwMouseButtonID;
+
+TW_API int      TW_CALL TwMouseButton(TwMouseAction action, TwMouseButtonID button);
+TW_API int      TW_CALL TwMouseMotion(int mouseX, int mouseY);
+TW_API int      TW_CALL TwMouseWheel(int pos);
+
+TW_API const char * TW_CALL TwGetLastError();
+typedef void (TW_CALL * TwErrorHandler)(const char *errorMessage);
+TW_API void     TW_CALL TwHandleErrors(TwErrorHandler errorHandler);
+
+
+// ----------------------------------------------------------------------------
+//  Helper functions to translate events from some common window management
+//  frameworks to AntTweakBar.
+//  They call TwKeyPressed, TwMouse* and TwWindowSize for you (implemented in
+//  files TwEventWin.c TwEventSDL.c TwEventGLFW.c TwEventGLUT.c)
+// ----------------------------------------------------------------------------
+
+//  For Windows message proc
+#ifndef _W64    // Microsoft specific (detection of 64 bits portability problems)
+#   define _W64
+#endif  // _W64
+TW_API int      TW_CALL TwEventWin(void *wnd, unsigned int msg, unsigned int _W64 wParam, int _W64 lParam);
+#define TwEventWin32    TwEventWin // For compatibility with AntTweakBar versions prior to 1.11
+
+//  For libSDL event loop
+TW_API int      TW_CALL TwEventSDL(const void *sdlEvent);
+ 
+//  For GLFW event callbacks
+TW_API int      TW_CALL TwEventMouseButtonGLFW(int glfwButton, int glfwAction);
+TW_API int      TW_CALL TwEventKeyGLFW(int glfwKey, int glfwAction);
+TW_API int      TW_CALL TwEventCharGLFW(int glfwChar, int glfwAction);
+#define TwEventMousePosGLFW     TwMouseMotion
+#define TwEventMouseWheelGLFW   TwMouseWheel
+
+//  For GLUT event callbacks (Windows calling convention for GLUT callbacks is cdecl)
+#if defined(_WIN32) || defined(_WIN64)
+#   define TW_GLUT_CALL __cdecl
+#else
+#   define TW_GLUT_CALL
+#endif
+TW_API int TW_GLUT_CALL TwEventMouseButtonGLUT(int glutButton, int glutState, int mouseX, int mouseY);
+TW_API int TW_GLUT_CALL TwEventMouseMotionGLUT(int mouseX, int mouseY);
+TW_API int TW_GLUT_CALL TwEventKeyboardGLUT(unsigned char glutKey, int mouseX, int mouseY);
+TW_API int TW_GLUT_CALL TwEventSpecialGLUT(int glutKey, int mouseX, int mouseY);
+TW_API int      TW_CALL TwGLUTModifiersFunc(int (TW_CALL *glutGetModifiersFunc)(void));
+typedef void (TW_GLUT_CALL *GLUTmousebuttonfun)(int glutButton, int glutState, int mouseX, int mouseY);
+typedef void (TW_GLUT_CALL *GLUTmousemotionfun)(int mouseX, int mouseY);
+typedef void (TW_GLUT_CALL *GLUTkeyboardfun)(unsigned char glutKey, int mouseX, int mouseY);
+typedef void (TW_GLUT_CALL *GLUTspecialfun)(int glutKey, int mouseX, int mouseY);
+
+ 
+// ----------------------------------------------------------------------------
+//  Make sure the types have the right sizes
+// ----------------------------------------------------------------------------
+
+#define TW_COMPILE_TIME_ASSERT(name, x) typedef int TW_DUMMY_ ## name[(x) * 2 - 1]
+
+TW_COMPILE_TIME_ASSERT(CHAR,    sizeof(char)    == 1);
+TW_COMPILE_TIME_ASSERT(SHORT,   sizeof(short)   == 2);
+TW_COMPILE_TIME_ASSERT(INT,     sizeof(int)     == 4);
+TW_COMPILE_TIME_ASSERT(FLOAT,   sizeof(float)   == 4);
+TW_COMPILE_TIME_ASSERT(DOUBLE,  sizeof(double)  == 8);
+
+
+//  ---------------------------------------------------------------------------
+
+
+#ifdef  __cplusplus
+    }   // extern "C"
+#endif  // __cplusplus
+
+
+#endif  // !defined TW_INCLUDED

+ 1 - 0
examples/ReAntTweakBar/static/libAntTweakBar.a.REMOVED.git-id

@@ -0,0 +1 @@
+c99c7d486e0f5e86a03def2cfb181bd2c5ff421a

+ 16 - 0
get_seconds.h

@@ -0,0 +1,16 @@
+#include <sys/time.h>
+
+namespace igl
+{
+  // Return the current time since Epoch in seconds
+  double get_seconds();
+}
+
+//Implementation
+
+double igl::get_seconds()
+{
+  timeval time;
+  gettimeofday(&time, NULL);
+  return time.tv_sec + time.tv_usec / 1e6;
+}

+ 14 - 0
material_colors.h

@@ -0,0 +1,14 @@
+// Define som constant material colors for use with opengl glMaterialfv
+namespace igl
+{
+  const float GOLD_AMBIENT[4] =   {  51.0/255.0, 43.0/255.0,33.3/255.0,1.0f };
+  const float GOLD_DIFFUSE[4] =   { 255.0/255.0,228.0/255.0,58.0/255.0,1.0f };
+  const float GOLD_SPECULAR[4] =  { 255.0/255.0,235.0/255.0,80.0/255.0,1.0f };
+  const float SILVER_AMBIENT[4] = { 0.2f, 0.2f, 0.2f, 1.0f };
+  const float SILVER_DIFFUSE[4] = { 1.0f, 1.0f, 1.0f, 1.0f };
+  const float SILVER_SPECULAR[4] = { 1.0f, 1.0f, 1.0f, 1.0f };
+  // Blue/Cyan more similar to Jovan Popovic's blue than to Mario Botsch's blue
+  const float CYAN_AMBIENT[4] =   {  59.0/255.0, 68.0/255.0,255.0/255.0,1.0f };
+  const float CYAN_DIFFUSE[4] =   {  94.0/255.0,185.0/255.0,238.0/255.0,1.0f };
+  const float CYAN_SPECULAR[4] =   { 163.0/255.0,221.0/255.0,255.0/255.0,1.0f };
+}

+ 28 - 0
verbose.h

@@ -0,0 +1,28 @@
+// Provide a macro for printf, called verbose that functions exactly like
+// printf if VERBOSE is defined and does exactly nothing if VERBOSE is
+// undefined
+#include <cstdio>
+#ifdef VERBOSE
+#  include <cstdarg>
+#endif
+
+namespace igl
+{
+  inline int verbose(const char * msg,...);
+};
+
+// Implementation
+
+// http://channel9.msdn.com/forums/techoff/254707-wrapping-printf-in-c/
+inline int igl::verbose(const char * msg,...)
+{
+#ifdef VERBOSE
+  va_list argList;
+  va_start(argList, msg);
+  int count = vprintf(msg, argList);
+  va_end(argList);
+  return count;
+#else
+  return 0;
+#endif
+}