diff options
Diffstat (limited to 'hw3/include')
56 files changed, 5071 insertions, 0 deletions
| diff --git a/hw3/include/.directory b/hw3/include/.directory new file mode 100644 index 0000000..f009e80 --- /dev/null +++ b/hw3/include/.directory @@ -0,0 +1,4 @@ +[Dolphin] +Timestamp=2016,2,3,13,45,20 +Version=3 +ViewMode=1 diff --git a/hw3/include/boundedCompound.h b/hw3/include/boundedCompound.h new file mode 100644 index 0000000..ab396f3 --- /dev/null +++ b/hw3/include/boundedCompound.h @@ -0,0 +1,55 @@ +/******************************************************************/ +/* This file is part of the homework assignments for CSCI-427/527 */ +/* at The College of William & Mary and authored by Pieter Peers. */ +/* No part of this file, whether altered or in original form, can */ +/* be distributed or used outside the context of CSCI-427/527     */ +/* without consent of either the College of William & Mary or     */ +/* Pieter Peers.                                                  */ +/******************************************************************/ +#ifndef _BOUNDED_COMPOUND_H_ +#define _BOUNDED_COMPOUND_H_ + +#include "intersector_base.h" +#include "transformation3d.h" +#include "boundedPrimitive.h" + +class boundedCompound : public boundedPrimitive { + public: +  ///////////////// +  // Constructor // +  ///////////////// +  boundedCompound(void); +  boundedCompound(const transformation3d& transform, const std::shared_ptr<const shader_base>& shader=nullptr); +  boundedCompound(const boundedCompound&) = delete; + +  /////////////// +  // Operators // +  /////////////// +  boundedCompound& operator=(const boundedCompound&) = delete; + +  ///////////// +  // Methods // +  ///////////// +  void initialize(const class intersector_factory_base& ifb); + +  virtual bool hasShader(void) const override; + +  virtual intersectionPoint intersect(const ray& r) const final override; + +  virtual const std::vector<std::shared_ptr<const boundedPrimitive>>& compounds(void) const = 0; + + protected: +  /////////////////////// +  // Protected Methods // +  /////////////////////// +  void initializeBoundingBox(void); +  virtual void _print(std::ostream& s) const override; + +  ////////////////// +  // Data Members // +  ////////////////// +  transformation3d _transform; +  std::unique_ptr<const intersector_base> _intersector; +}; + +#endif /* _BOUNDED_COMPOUND_H_ */ diff --git a/hw3/include/boundedPrimitive.h b/hw3/include/boundedPrimitive.h new file mode 100644 index 0000000..ef467a2 --- /dev/null +++ b/hw3/include/boundedPrimitive.h @@ -0,0 +1,67 @@ +/******************************************************************/ +/* This file is part of the homework assignments for CSCI-427/527 */ +/* at The College of William & Mary and authored by Pieter Peers. */ +/* No part of this file, whether altered or in original form, can */ +/* be distributed or used outside the context of CSCI-427/527     */ +/* without consent of either the College of William & Mary or     */ +/* Pieter Peers.                                                  */ +/******************************************************************/ +#ifndef _BOUNDED_PRIMITIVE_H_ +#define _BOUNDED_PRIMITIVE_H_ + +#include <vector> +#include <memory> +#include <ostream> + +#include "ray.h" +#include "shader_base.h" +#include "boundingBox.h" +#include "intersectionPoint.h" + +class boundedPrimitive { + public: +  ///////////////// +  // Constructor // +  ///////////////// +  boundedPrimitive(void); +  boundedPrimitive(const boundingBox& bb, const std::shared_ptr<const shader_base>& shader); +  boundedPrimitive(const boundedPrimitive&) = delete; + +  /////////////// +  // Operators // +  /////////////// +  boundedPrimitive& operator=(const boundedPrimitive& ) = delete; + +  ///////////// +  // Methods // +  ///////////// +  const boundingBox& boundingbox(void) const; +  bool hitBoundingBox(const ray& r) const; +  virtual bool hasShader(void) const; + +  virtual intersectionPoint intersect(const ray& r) const = 0; + +  ///////////// +  // Friends // +  ///////////// +  friend std::ostream& operator<<(std::ostream& s, const boundedPrimitive& bp) +  { +    bp._print(s); +    return s; +  } + + protected: +  /////////////////////// +  // Protected Methods // +  /////////////////////// +  virtual void _print(std::ostream& s) const; + +  ////////////////// +  // Data Members // +  ////////////////// +  boundingBox _bb; +  std::shared_ptr<const shader_base> _shader; +}; + +#endif /* _BOUNDED_PRIMITIVE_H_ */ + diff --git a/hw3/include/boundedTriangle.h b/hw3/include/boundedTriangle.h new file mode 100644 index 0000000..965c0ff --- /dev/null +++ b/hw3/include/boundedTriangle.h @@ -0,0 +1,46 @@ +/******************************************************************/ +/* This file is part of the homework assignments for CSCI-427/527 */ +/* at The College of William & Mary and authored by Pieter Peers. */ +/* No part of this file, whether altered or in original form, can */ +/* be distributed or used outside the context of CSCI-427/527     */ +/* without consent of either the College of William & Mary or     */ +/* Pieter Peers.                                                  */ +/******************************************************************/ +#ifndef _BOUNDEDTRIANGLE_H_  +#define _BOUNDEDTRIANGLE_H_  + +#include "triangle.h" +#include "boundedPrimitive.h" + +class boundedTriangle : public boundedPrimitive { + public: +  ////////////////// +  // Constructors // +  ////////////////// +  boundedTriangle(void); +  boundedTriangle(const triangle& tri, const std::shared_ptr<const shader_base>& shader); +  boundedTriangle(const boundedTriangle&) = delete; + +  /////////////// +  // Operators // +  /////////////// +  boundedTriangle& operator=(const boundedTriangle&) = delete; + +  ///////////// +  // Methods // +  ///////////// +  virtual intersectionPoint intersect(const ray& r) const final override; + + private: +  /////////////////////// +  // Protected Methods // +  /////////////////////// +  virtual void _print(std::ostream& s) const override; + +  ////////////////// +  // Data Members // +  ////////////////// +  triangle _triangle; +}; + +#endif /* _BOUNDEDTRIANGLE_H_ */ diff --git a/hw3/include/boundingBox.h b/hw3/include/boundingBox.h new file mode 100644 index 0000000..522672e --- /dev/null +++ b/hw3/include/boundingBox.h @@ -0,0 +1,77 @@ +/******************************************************************/ +/* This file is part of the homework assignments for CSCI-427/527 */ +/* at The College of William & Mary and authored by Pieter Peers. */ +/* No part of this file, whether altered or in original form, can */ +/* be distributed or used outside the context of CSCI-427/527     */ +/* without consent of either the College of William & Mary or     */ +/* Pieter Peers.                                                  */ +/******************************************************************/ +#ifndef _BOUNDINGBOX_H_ +#define _BOUNDINGBOX_H_ + +#include <ostream> + +#include "ray.h" +#include "vec3d.h" +#include "transformation3d.h" + +class boundingBox { + public: +  ///////////////// +  // Constructor // +  ///////////////// +  boundingBox(void); +  boundingBox(const vec3d& lfb, const vec3d& rbt); +  boundingBox(const boundingBox& bb); + +  ////////////// +  // Operator // +  ////////////// +  boundingBox& operator=(const boundingBox& src); +   +  boundingBox& operator+=(const boundingBox& bb); +  boundingBox& operator+=(const vec3d& point); + +  boundingBox operator+(const boundingBox& bb) const; + +  ///////////// +  // Methods // +  ///////////// +  bool isHit(const ray& r) const; + +  vec3d center(void) const; +  vec3d corner(bool left, bool front, bool bottom) const; + +  ////////////// +  // Mutators // +  ////////////// +  boundingBox& transform(const transformation3d& t); +  boundingBox& inverseTransform(const transformation3d& t); + +  ///////////// +  // Friends // +  ///////////// +  friend void swap(boundingBox& a, boundingBox& b) { a._swap(b); } +  friend boundingBox transform(const boundingBox& bb, const transformation3d& t) { return boundingBox(bb).transform(t); } +  friend boundingBox inverseTransform(const boundingBox& bb, const transformation3d& t) { return boundingBox(bb).inverseTransform(t); } +  friend std::ostream& operator<<(std::ostream& s, const boundingBox& bb) +  { +    s << bb._lfb << " - " << bb._rbt; +    return s; +  } + + private: +  ///////////////////// +  // Private Methods // +  ///////////////////// +  void _swap(boundingBox& bb); +  void _assign(const boundingBox& bb);  + +  ////////////////// +  // Data Members // +  ////////////////// +  vec3d _lfb, _rbt; +}; + + +#endif /* _BOUNDINGBOX_H_ */ diff --git a/hw3/include/brdf_base.h b/hw3/include/brdf_base.h new file mode 100644 index 0000000..e0d8009 --- /dev/null +++ b/hw3/include/brdf_base.h @@ -0,0 +1,47 @@ +/******************************************************************/ +/* This file is part of the homework assignments for CSCI-427/527 */ +/* at The College of William & Mary and authored by Pieter Peers. */ +/* No part of this file, whether altered or in original form, can */ +/* be distributed or used outside the context of CSCI-427/527     */ +/* without consent of either the College of William & Mary or     */ +/* Pieter Peers.                                                  */ +/******************************************************************/ +#ifndef _BRDF_BASE_H_ +#define _BRDF_BASE_H_ + +#include <ostream> +#include "vec3d.h" +#include "color.h" + +class brdf_base { + public: +  ///////////// +  // Methods // +  ///////////// + +  // Note: 'in' and 'out' point away from the surface point +  // Note: 'in' and 'out' are specified in the local shading frame, +  //       where the normal=(0.0, 0.0, 1.0). +  virtual color shade(const vec3d& in, const vec3d& out) const = 0; + +  // returns true if BRDF has a specular/diffuse component +  virtual bool isSpecular(void) const = 0; +  virtual bool isDiffuse(void) const = 0; + +  ///////////// +  // Friends // +  ///////////// +  friend std::ostream& operator<<(std::ostream& s, const brdf_base& b) +  { +    b._print(s); +    return s; +  } + + private: +  ///////////////////// +  // Private Methods // +  ///////////////////// +  virtual void _print(std::ostream& s) const = 0; +}; + +#endif /* _BRDF_BASE_H_ */ diff --git a/hw3/include/camera.h b/hw3/include/camera.h new file mode 100644 index 0000000..9e3be04 --- /dev/null +++ b/hw3/include/camera.h @@ -0,0 +1,80 @@ +/******************************************************************/ +/* This file is part of the homework assignments for CSCI-427/527 */ +/* at The College of William & Mary and authored by Pieter Peers. */ +/* No part of this file, whether altered or in original form, can */ +/* be distributed or used outside the context of CSCI-427/527     */ +/* without consent of either the College of William & Mary or     */ +/* Pieter Peers.                                                  */ +/******************************************************************/ +#ifndef _CAMERA_H_ +#define _CAMERA_H_ + +#include <ostream> + +#include "ray.h" +#include "vec2d.h" +#include "boundingBox.h" + +/**************************************************************/ +/* Note: Field of View (fov) is expressed in degrees, and     */ +/* represents the angular spread in the horizontal direction. */ +/**************************************************************/ +class camera { + public: +  ///////////////// +  // Constructor // +  ///////////////// +  camera(void); +  camera(const vec3d& eye, const vec3d& viewDirection, const vec3d& up, float fov, size_t xres, size_t yres); +  camera(const camera& cam); + +  /////////////// +  // Operators // +  /////////////// +  camera& operator=(const camera& cam); + +  ray operator()(float x, float y) const; + +  //////////////// +  // Inspectors // +  //////////////// +  size_t width(void) const { return _width; } +  size_t height(void) const { return _height; } + +  ////////////// +  // Mutators // +  ////////////// +  void frameBoundingBox(const boundingBox& bb); + +  ///////////// +  // Friends // +  ///////////// +  friend void swap(camera& a, camera& b) { a._swap(b); } +  friend std::ostream& operator<<(std::ostream& s, const camera& cam) +  { +    s << "Camera: {"; +    s << "eye=" << cam._eye << ", "; +    s << "view=" << cam._view << ", "; +    s << "up=" << cam._up << "}, "; +    s << "fov=" << cam._fov << ", "; +    s << "resolution=[" << cam._width << "x" << cam._height << "]"; +    return s; +  } + + private: +  ///////////////////// +  // Private Methods // +  ///////////////////// +  void _swap(camera& cam); +  void _assign(const camera& cam); + +  ////////////////// +  // Data Members // +  ////////////////// +  vec3d _eye, _view, _up; +  float _fov; +  size_t _width, _height; +}; + +#endif /* _CAMERA_H_ */ + diff --git a/hw3/include/color.h b/hw3/include/color.h new file mode 100644 index 0000000..b2ca490 --- /dev/null +++ b/hw3/include/color.h @@ -0,0 +1,105 @@ +/******************************************************************/ +/* This file is part of the homework assignments for CSCI-427/527 */ +/* at The College of William & Mary and authored by Pieter Peers. */ +/* No part of this file, whether altered or in original form, can */ +/* be distributed or used outside the context of CSCI-427/527     */ +/* without consent of either the College of William & Mary or     */ +/* Pieter Peers.                                                  */ +/******************************************************************/ +#ifndef _COLOR_H_ +#define _COLOR_H_ + +#include <ostream> + +class color { + public: +  ///////////// +  // Typedef // +  ///////////// +  typedef float                 value_type; +  typedef value_type&           reference; +  typedef const value_type&     const_reference; +  typedef value_type*           iterator; +  typedef const value_type*     const_iterator; + +  ////////////////// +  // Data Members // +  ////////////////// +  union { +    struct { value_type r, g, b; }; +    struct { value_type red, green, blue; }; +    value_type data[3]; +  }; + + public: +  ///////////////// +  // Constructor // +  ///////////////// +  explicit color(const_reference value=0.0f); +  color(const_reference r, const_reference g, const_reference b); +  color(const color& col); +  +  //////////////// +  // Inspectors // +  //////////////// +  const_reference operator[](size_t index) const; +  reference operator[](size_t index); + +  size_t size(void) const { return 3; } + +  iterator begin(void); +  const_iterator begin(void) const; +  iterator end(void); +  const_iterator end(void) const; + +  /////////////// +  // Operators // +  /////////////// +  color& operator=(const color& col); + +  bool operator==(const color& col) const; +  bool operator!=(const color& col) const; +   +  color operator+(const color& col) const; +  color operator-(const color& col) const; +  color operator*(const color& col) const; +  color operator*(const_reference scale) const; +  color operator/(const color& col) const; +  color operator/(const_reference scale) const; + +  color& operator+=(const color& col); +  color& operator-=(const color& col); +  color& operator*=(const color& col); +  color& operator*=(const_reference scale); +  color& operator/=(const color& col); +  color& operator/=(const_reference scale); + +  /////////////// +  // Modifiers // +  /////////////// +  color& abs(void); +  color& clamp(const_reference lowerBound=0.0f, const_reference upperBounds=1.0f); + +  ///////////// +  // Friends // +  ///////////// +  friend void  swap(color& a, color& b) { return a._swap(b); } +  friend color abs(const color& c) { return color(c).abs(); } +  friend color clamp(const color& c, const_reference lowerBound=0.0f, const_reference upperBound=1.0f) { return color(c).clamp(lowerBound, upperBound); } +  friend color operator*(const_reference scale, const color& col) { return (col*scale); } + +  friend std::ostream& operator<<(std::ostream& s, const color& col) +  { +    s << "(" << col.r << "," << col.g << "," << col.b << ")"; +    return s; +  } + + private: +  ///////////////////// +  // Private Methods // +  ///////////////////// +  void _assign(const color& col); +  void _swap(color& col); +}; + +#endif /* _COLOR_H_ */ diff --git a/hw3/include/compoundShader.h b/hw3/include/compoundShader.h new file mode 100644 index 0000000..293e7d6 --- /dev/null +++ b/hw3/include/compoundShader.h @@ -0,0 +1,51 @@ +/******************************************************************/ +/* This file is part of the homework assignments for CSCI-427/527 */ +/* at The College of William & Mary and authored by Pieter Peers. */ +/* No part of this file, whether altered or in original form, can */ +/* be distributed or used outside the context of CSCI-427/527     */ +/* without consent of either the College of William & Mary or     */ +/* Pieter Peers.                                                  */ +/******************************************************************/ +#ifndef _COMPOUND_SHADER_H_ +#define _COMPOUND_SHADER_H_ + +#include <vector> +#include <memory> + +#include "shader_base.h" + +class compoundShader : public shader_base { + public: +  ////////////////// +  // Constructors // +  ////////////////// +  compoundShader(const std::vector<std::shared_ptr<const shader_base>>& shader_list); +  compoundShader(const compoundShader&) = delete; + +  /////////////// +  // Operators // +  /////////////// +  compoundShader& operator=(const compoundShader&) = delete; + +  ///////////// +  // Methods // +  ///////////// +  virtual color shade(const intersectionPoint& ip, const vec3d& light_dir) const override; + +  virtual shaderProperties properties(const intersectionPoint& ip) const override; + + + protected: +  /////////////////////// +  // Protected Methods // +  /////////////////////// +  virtual void _print(std::ostream& s) const override; + + private: +  ////////////////// +  // Data Members // +  ////////////////// +  std::vector<std::shared_ptr<const shader_base>> _compound; +}; + +#endif /* _COMPOUND_SHADER_H_ */ diff --git a/hw3/include/constants.h b/hw3/include/constants.h new file mode 100644 index 0000000..daa1c45 --- /dev/null +++ b/hw3/include/constants.h @@ -0,0 +1,16 @@ +/******************************************************************/ +/* This file is part of the homework assignments for CSCI-427/527 */ +/* at The College of William & Mary and authored by Pieter Peers. */ +/* No part of this file, whether altered or in original form, can */ +/* be distributed or used outside the context of CSCI-427/527     */ +/* without consent of either the College of William & Mary or     */ +/* Pieter Peers.                                                  */ +/******************************************************************/ +#ifndef _CONSTANTS_H_ +#define _CONSTANTS_H_ + +static const float EPSILON = 10e-6; +static const float LARGE   = 10e10; +static const float PI      = 3.14159265359; + +#endif /* _CONSTANTS_H_ */ diff --git a/hw3/include/coordinateTransform.h b/hw3/include/coordinateTransform.h new file mode 100644 index 0000000..008cba7 --- /dev/null +++ b/hw3/include/coordinateTransform.h @@ -0,0 +1,31 @@ +/******************************************************************/ +/* This file is part of the homework assignments for CSCI-427/527 */ +/* at The College of William & Mary and authored by Pieter Peers. */ +/* No part of this file, whether altered or in original form, can */ +/* be distributed or used outside the context of CSCI-427/527     */ +/* without consent of either the College of William & Mary or     */ +/* Pieter Peers.                                                  */ +/******************************************************************/ +#ifndef _COORDINATETRANSFORMATION3D_H_ +#define _COORDINATETRANSFORMATION3D_H_ + +#include "transformation3d.h" + +/////////////////////////////////////////////// +// Transformation between coordinate systems // +// forward transform: from local to global   // +// inverse transform: from global to local   // +/////////////////////////////////////////////// +class coordinateTransformation : public transformation3d { + public: +  ////////////////// +  // Constructors // +  ////////////////// +  coordinateTransformation(void); +  coordinateTransformation(const vec3d& normal); +  coordinateTransformation(const vec3d& normal, const vec3d& other); +  coordinateTransformation(const vec3d& X, const vec3d& Y, const vec3d& Z); +}; + +#endif /* _COORDINATETRANSFORMATION3D_H_ */ + diff --git a/hw3/include/diffuseBrdf.h b/hw3/include/diffuseBrdf.h new file mode 100644 index 0000000..e4ab19f --- /dev/null +++ b/hw3/include/diffuseBrdf.h @@ -0,0 +1,59 @@ +/******************************************************************/ +/* This file is part of the homework assignments for CSCI-427/527 */ +/* at The College of William & Mary and authored by Pieter Peers. */ +/* No part of this file, whether altered or in original form, can */ +/* be distributed or used outside the context of CSCI-427/527     */ +/* without consent of either the College of William & Mary or     */ +/* Pieter Peers.                                                  */ +/******************************************************************/ +#ifndef _DIFFUSEBRDF_H_ +#define _DIFFUSEBRDF_H_ + +#include "brdf_base.h" + +class diffuseBrdf : public brdf_base { + public: +  ////////////////// +  // Constructors // +  ////////////////// +  diffuseBrdf(const color& albedo); +  diffuseBrdf(const diffuseBrdf& src); + +  /////////////// +  // Operators // +  /////////////// +  diffuseBrdf& operator=(const diffuseBrdf& src); + +  ///////////// +  // Methods // +  ///////////// +  virtual color shade(const vec3d& in, const vec3d& out) const final override; + +  virtual bool isSpecular(void) const final override; +  virtual bool isDiffuse(void) const final override; + +  ///////////// +  // Friends // +  ///////////// +  friend void swap(diffuseBrdf& a, diffuseBrdf& b) { a._swap(b); } +  friend std::ostream& operator<<(std::ostream& s, const diffuseBrdf& b) +  { +    b._print(s); +    return s; +  } + + private: +  ///////////////////// +  // Private Methods // +  ///////////////////// +  void _assign(const diffuseBrdf& src); +  void _swap(diffuseBrdf& src); +  virtual void _print(std::ostream& s) const override; + +  ////////////////// +  // Data Members // +  ////////////////// +  color _albedo; +}; + +#endif /* _DIFFUSEBRDF_H_ */ diff --git a/hw3/include/diffuseReflectanceShader.h b/hw3/include/diffuseReflectanceShader.h new file mode 100644 index 0000000..bee9d8d --- /dev/null +++ b/hw3/include/diffuseReflectanceShader.h @@ -0,0 +1,45 @@ +/******************************************************************/ +/* This file is part of the homework assignments for CSCI-427/527 */ +/* at The College of William & Mary and authored by Pieter Peers. */ +/* No part of this file, whether altered or in original form, can */ +/* be distributed or used outside the context of CSCI-427/527     */ +/* without consent of either the College of William & Mary or     */ +/* Pieter Peers.                                                  */ +/******************************************************************/ +#ifndef _DIFFUSEREFLECTANCESHADER_H_ +#define _DIFFUSEREFLECTANCESHADER_H_ + +#include "diffuseBrdf.h" +#include "reflectanceParameter.h" +#include "reflectanceShader_base.h" + +class diffuseReflectanceShader : public reflectanceShader_base { + public: +  ///////////////// +  // Constructor // +  ///////////////// +  diffuseReflectanceShader(const colorReflectanceParameter& albedo=colorReflectanceParameter(color(1.0f, 1.0f, 1.0f))); +  diffuseReflectanceShader(const diffuseReflectanceShader& ) = delete; + +  /////////////// +  // Operators // +  /////////////// +  diffuseReflectanceShader& operator=(const diffuseReflectanceShader&) = delete; + +protected: +  /////////////////////// +  // Protected Methods // +  /////////////////////// +  virtual std::unique_ptr<const brdf_base> make_brdf(const vec2d& textureCoord) const override; + +  virtual void _print(std::ostream& s) const override; + +private: +  ////////////////// +  // Data Members // +  ////////////////// +  colorReflectanceParameter _albedo; +}; + +#endif /* _DIFFUSEREFLECTANCESHADER_H_ */ + diff --git a/hw3/include/directionalLightsource.h b/hw3/include/directionalLightsource.h new file mode 100644 index 0000000..b33dfaf --- /dev/null +++ b/hw3/include/directionalLightsource.h @@ -0,0 +1,55 @@ +/******************************************************************/ +/* This file is part of the homework assignments for CSCI-427/527 */ +/* at The College of William & Mary and authored by Pieter Peers. */ +/* No part of this file, whether altered or in original form, can */ +/* be distributed or used outside the context of CSCI-427/527     */ +/* without consent of either the College of William & Mary or     */ +/* Pieter Peers.                                                  */ +/******************************************************************/ +#ifndef _DIRECTIONALLIGHTSOURCE_H_ +#define _DIRECTIONALLIGHTSOURCE_H_ + +#include "lightsource_base.h" + +class directionalLightsource : public lightsource_base { + public: +  ////////////////// +  // Constructors // +  ////////////////// +  directionalLightsource(const vec3d& direction=vec3d(0.0f, 0.0f, 1.0f), const color& power=color(1.0f, 1.0f, 1.0f)); +  directionalLightsource(const directionalLightsource&) = delete; + +  /////////////// +  // Operators // +  /////////////// +  directionalLightsource& operator=(const directionalLightsource&) = delete; + +  ///////////// +  // Methods // +  ///////////// +  virtual lightSample intensityAt(const vec3d& point) const override;   + +  ///////////// +  // Friends // +  ///////////// +  friend std::ostream& operator<<(std::ostream& s, const directionalLightsource& d) +  { +    d._print(s); +    return s; +  } + + private: +  ///////////////////// +  // Private Methods // +  ///////////////////// +  virtual void _print(std::ostream& s) const override; + + private: +  ////////////////// +  // Data Members // +  ////////////////// +  vec3d _direction; +  color _power; +}; + +#endif /* _DIRECTIONALLIGHTSOURCE_H_ */ diff --git a/hw3/include/errorMessage.h b/hw3/include/errorMessage.h new file mode 100644 index 0000000..7ec99d1 --- /dev/null +++ b/hw3/include/errorMessage.h @@ -0,0 +1,17 @@ +/******************************************************************/ +/* This file is part of the homework assignments for CSCI-427/527 */ +/* at The College of William & Mary and authored by Pieter Peers. */ +/* No part of this file, whether altered or in original form, can */ +/* be distributed or used outside the context of CSCI-427/527     */ +/* without consent of either the College of William & Mary or     */ +/* Pieter Peers.                                                  */ +/******************************************************************/ +#ifndef _ERROR_MESSAGE_H_ +#define _ERROR_MESSAGE_H_ + +#include <cstdarg> + +void errorMessage(const char* msg, ...); +void warningMessage(const char* msg, ...); + +#endif /* _ERROR_MESSAGE_H_ */ diff --git a/hw3/include/image.h b/hw3/include/image.h new file mode 100644 index 0000000..938e6c0 --- /dev/null +++ b/hw3/include/image.h @@ -0,0 +1,89 @@ +/******************************************************************/ +/* This file is part of the homework assignments for CSCI-427/527 */ +/* at The College of William & Mary and authored by Pieter Peers. */ +/* No part of this file, whether altered or in original form, can */ +/* be distributed or used outside the context of CSCI-427/527     */ +/* without consent of either the College of William & Mary or     */ +/* Pieter Peers.                                                  */ +/******************************************************************/ +#ifndef _IMAGE_H_ +#define _IMAGE_H_ + +#include <string> +#include <memory> +#include <ostream> + +#include "color.h" + +class image { + public: +  ////////////// +  // Typedefs // +  ////////////// +  typedef color                                         value_type; +  typedef value_type&                                   reference; +  typedef const value_type&                             const_reference; +  typedef std::unique_ptr<value_type[]>::pointer        iterator; +  typedef std::unique_ptr<const value_type[]>::pointer  const_iterator; +  typedef size_t                                        difference_type; +  typedef size_t                                        size_type; + +  ////////////////// +  // Constructors // +  ////////////////// +  image(size_type width=0, size_type height=0); +  image(size_type width, size_type height, const_reference col); +  image(const image& src); +  image(image&& src); + +  virtual ~image(void) { _data.reset(); } + +  //////////////// +  // Inspectors // +  //////////////// +  iterator begin(void); +  const_iterator begin(void) const; +   +  iterator end(void); +  const_iterator end(void) const; + +  size_type size(void) const   { return width()*height(); } +  size_type width(void) const  { return _width; } +  size_type height(void) const { return _height; } + + +  /////////////// +  // Operators // +  /////////////// +  image& operator=(const image& src); +  image& operator=(image&& src); + +  reference operator()(size_type x, size_type y); +  const_reference operator()(size_type x, size_type y) const; + +  ///////////// +  // Friends // +  ///////////// +  friend void swap(image& a, image& b) { a._swap(b); } +  friend std::ostream& operator<<(std::ostream& s, const image& img) +  { +    s << "Image: (" << img.width() << ", " << img.height() << ")"; +    return s; +  } + +protected: +  ///////////////////// +  // Private Methods // +  ///////////////////// +  void _swap(image& img); +  void _assign(const image& src); + +private: +  ////////////////////////// +  // Private Data Members // +  ////////////////////////// +  size_type _width, _height; +  std::unique_ptr<value_type[]> _data; +}; + +#endif /* _IMAGE_H_ */ diff --git a/hw3/include/imageIO.h b/hw3/include/imageIO.h new file mode 100644 index 0000000..9e1ecfa --- /dev/null +++ b/hw3/include/imageIO.h @@ -0,0 +1,19 @@ +/******************************************************************/ +/* This file is part of the homework assignments for CSCI-427/527 */ +/* at The College of William & Mary and authored by Pieter Peers. */ +/* No part of this file, whether altered or in original form, can */ +/* be distributed or used outside the context of CSCI-427/527     */ +/* without consent of either the College of William & Mary or     */ +/* Pieter Peers.                                                  */ +/******************************************************************/ +#ifndef _IMAGEIO_H_ +#define _IMAGEIO_H_ + +#include <string> +#include "image.h" + +void importImage(const std::string& name, image& img); +void exportImage(const std::string& name, const image& img); + +#endif /* _IMAGEIO_H_ */ + diff --git a/hw3/include/imageIO.pfm.h b/hw3/include/imageIO.pfm.h new file mode 100644 index 0000000..d09531a --- /dev/null +++ b/hw3/include/imageIO.pfm.h @@ -0,0 +1,18 @@ +/******************************************************************/ +/* This file is part of the homework assignments for CSCI-427/527 */ +/* at The College of William & Mary and authored by Pieter Peers. */ +/* No part of this file, whether altered or in original form, can */ +/* be distributed or used outside the context of CSCI-427/527     */ +/* without consent of either the College of William & Mary or     */ +/* Pieter Peers.                                                  */ +/******************************************************************/ +#ifndef _IMAGEIO_PFM_H_ +#define _IMAGEIO_PFM_H_ + +#include <string> +#include "image.h" + +void importPFM(const std::string& name, image& img); +void exportPFM(const std::string& name, const image& img); + +#endif /* _IMAGEIO_PFM_H_ */ diff --git a/hw3/include/imageIO.ppm.h b/hw3/include/imageIO.ppm.h new file mode 100644 index 0000000..7a8db42 --- /dev/null +++ b/hw3/include/imageIO.ppm.h @@ -0,0 +1,18 @@ +/******************************************************************/ +/* This file is part of the homework assignments for CSCI-427/527 */ +/* at The College of William & Mary and authored by Pieter Peers. */ +/* No part of this file, whether altered or in original form, can */ +/* be distributed or used outside the context of CSCI-427/527     */ +/* without consent of either the College of William & Mary or     */ +/* Pieter Peers.                                                  */ +/******************************************************************/ +#ifndef _IMAGEIO_PPM_H_ +#define _IMAGEIO_PPM_H_ + +#include <string> +#include "image.h" + +void importPPM(const std::string& name, image& img); +void exportPPM(const std::string& name, const image& img); + +#endif /* _IMAGEIO_PPM_H_ */ diff --git a/hw3/include/importOBJ.h b/hw3/include/importOBJ.h new file mode 100644 index 0000000..056a420 --- /dev/null +++ b/hw3/include/importOBJ.h @@ -0,0 +1,18 @@ +/******************************************************************/ +/* This file is part of the homework assignments for CSCI-427/527 */ +/* at The College of William & Mary and authored by Pieter Peers. */ +/* No part of this file, whether altered or in original form, can */ +/* be distributed or used outside the context of CSCI-427/527     */ +/* without consent of either the College of William & Mary or     */ +/* Pieter Peers.                                                  */ +/******************************************************************/ +#ifndef _IMPORTOBJ_H_ +#define _IMPORTOBJ_H_ + +#include <string> +#include <vector> +#include "triangle.h" + +void importOBJ(const std::string filename, std::vector<triangle>& triangle_list); + +#endif /* _IMPORTOBJ_H_ */  diff --git a/hw3/include/intersectionPoint.h b/hw3/include/intersectionPoint.h new file mode 100644 index 0000000..a4d8888 --- /dev/null +++ b/hw3/include/intersectionPoint.h @@ -0,0 +1,110 @@ +/******************************************************************/ +/* This file is part of the homework assignments for CSCI-427/527 */ +/* at The College of William & Mary and authored by Pieter Peers. */ +/* No part of this file, whether altered or in original form, can */ +/* be distributed or used outside the context of CSCI-427/527     */ +/* without consent of either the College of William & Mary or     */ +/* Pieter Peers.                                                  */ +/******************************************************************/ +#ifndef _INTERSECTIONPOINT_H_ +#define _INTERSECTIONPOINT_H_ + +#include <memory> +#include <ostream> + +#include "ray.h" +#include "vec3d.h" +#include "vec2d.h" +#include "color.h" +#include "constants.h" +#include "lightSample.h" +#include "transformation3d.h" +#include "shaderProperties.h" +#include "coordinateTransform.h" + + +class intersectionPoint  +{ + public: +  ///////////////// +  // Constructor // +  ///////////////// +  intersectionPoint(void); +  intersectionPoint(const ray& r, float rayParameter=+LARGE, const std::shared_ptr<const class shader_base>& shader=nullptr, const vec3d& normal=vec3d(0.0f, 0.0f, 1.0f), const vec3d& U=vec3d(1.0f, 0.0f, 0.0f), const vec2d& textureCoordinate=vec2d(0.0f, 0.0f)); +  intersectionPoint(const intersectionPoint& ip); + +  /////////////// +  // Operators // +  /////////////// +  intersectionPoint& operator=(const intersectionPoint& ip); + +  bool operator<(const intersectionPoint& ip) const; +  bool operator>(const intersectionPoint& ip) const; +  bool operator<(const lightSample& ls) const; +  bool operator>(const lightSample& ls) const; + +  //////////////// +  // Inspectors // +  //////////////// +  bool isHit(void) const; +  bool hasShader(void) const; +  shaderProperties getShaderProperties(void) const; +  float distance(const intersectionPoint& ip) const; +  const vec3d& position(void) const; +  const vec3d& direction(void) const; +  const vec2d& textureCoordinate(void) const; +  const vec3d& normal(void) const; +  coordinateTransformation shadingFrame(void) const; + +  ////////////// +  // Mutators // +  ////////////// +  void transform(const transformation3d& t); +  void inverseTransform(const transformation3d& t); + +  void transformShadingFrame(const transformation3d& sft); +  void inverseTransformShadingFrame(const transformation3d& sft); + +  void setShader(const std::shared_ptr<const class shader_base>& shader); + +  ///////////// +  // Methods // +  ///////////// +  color shade(const vec3d& out) const; +  color shade(const lightSample& ls) const; + +  ///////////// +  // Friends // +  ///////////// +  friend void swap(intersectionPoint& a, intersectionPoint& b) { a._swap(b); } + +  friend bool operator<(const lightSample& ls, const intersectionPoint& ip) { return (ip > ls); } +  friend bool operator>(const lightSample& ls, const intersectionPoint& ip) { return (ip < ls); } + +  friend std::ostream& operator<<(std::ostream& s, const intersectionPoint& ip) +  { +    if(ip._hit) s << "IntersectionPoint: ray=" << ip._ray << ", position=" << ip._position << " (parameter=" << ip._rayParameter << ", normal=" << ip._normal << ", shading axis=" << ip._U << ", texture coordinate=" << ip._textureCoordinate; +    else s << "IntersectionPoint: empty"; +    return s; +  } + + private: +  ///////////////////// +  // Private Methods // +  ///////////////////// +  void _assign(const intersectionPoint& ip); +  void _swap(intersectionPoint& ip); + +  ////////////////// +  // Data Members // +  ////////////////// +  ray _ray; +  bool _hit; +  float _rayParameter; +  vec3d _position; +  vec3d _normal, _U; +  vec2d _textureCoordinate; +  std::shared_ptr<const class shader_base> _shader; +}; + +#endif /* _INTERSECTIONPOINT_H_ */ diff --git a/hw3/include/intersector_base.h b/hw3/include/intersector_base.h new file mode 100644 index 0000000..64fb05e --- /dev/null +++ b/hw3/include/intersector_base.h @@ -0,0 +1,34 @@ +/******************************************************************/ +/* This file is part of the homework assignments for CSCI-427/527 */ +/* at The College of William & Mary and authored by Pieter Peers. */ +/* No part of this file, whether altered or in original form, can */ +/* be distributed or used outside the context of CSCI-427/527     */ +/* without consent of either the College of William & Mary or     */ +/* Pieter Peers.                                                  */ +/******************************************************************/ +#ifndef _INTERSECTOR_BASE_H_ +#define _INTERSECTOR_BASE_H_ + +#include "ray.h" +#include "intersectionPoint.h" + +class intersector_base { + public: +  ////////////////// +  // Constructors // +  ////////////////// +  intersector_base(void) {} +  intersector_base(const intersector_base&) = delete; +   +  /////////////// +  // Operators // +  /////////////// +  intersector_base& operator=(const intersector_base&) = delete; + +  ///////////// +  // Methods // +  ///////////// +  virtual intersectionPoint intersect(const ray& r) const = 0; +}; + +#endif /* _INTERSECTOR_BASE_H_ */ diff --git a/hw3/include/intersector_factory_base.h b/hw3/include/intersector_factory_base.h new file mode 100644 index 0000000..c6e9e98 --- /dev/null +++ b/hw3/include/intersector_factory_base.h @@ -0,0 +1,29 @@ +/******************************************************************/ +/* This file is part of the homework assignments for CSCI-427/527 */ +/* at The College of William & Mary and authored by Pieter Peers. */ +/* No part of this file, whether altered or in original form, can */ +/* be distributed or used outside the context of CSCI-427/527     */ +/* without consent of either the College of William & Mary or     */ +/* Pieter Peers.                                                  */ +/******************************************************************/ +#ifndef _INTERSECTOR_FACTORY_BASE_H_ +#define _INTERSECTOR_FACTORY_BASE_H_ + +#include <memory> +#include "boundedCompound.h" +#include "intersector_base.h" + +class intersector_factory_base { +public: +  ///////////////// +  // Constructor // +  ///////////////// +  intersector_factory_base(void) {} + +  ////////////// +  // Operator // +  ////////////// +  virtual std::unique_ptr<const intersector_base> operator()(const boundedCompound& bc) const = 0; +}; + +#endif /* _INTERSECTOR_FACTORY_BASE_H_ */ diff --git a/hw3/include/interval.h b/hw3/include/interval.h new file mode 100644 index 0000000..ccb720a --- /dev/null +++ b/hw3/include/interval.h @@ -0,0 +1,77 @@ +/******************************************************************/ +/* This file is part of the homework assignments for CSCI-427/527 */ +/* at The College of William & Mary and authored by Pieter Peers. */ +/* No part of this file, whether altered or in original form, can */ +/* be distributed or used outside the context of CSCI-427/527     */ +/* without consent of either the College of William & Mary or     */ +/* Pieter Peers.                                                  */ +/******************************************************************/ +#ifndef _INTERVAL_H_ +#define _INTERVAL_H_ + +#include <ostream> + +#include "constants.h" + +class interval +{ + public: +  ////////////////// +  // Constrructor // +  ////////////////// +  interval(float lower=-LARGE, float upper=+LARGE); +  interval(const interval& i); + +  /////////////// +  // Operators // +  /////////////// +  interval& operator=(const interval& i); + +  interval operator+(float v) const; +  interval operator-(float v) const; +  interval operator*(float v) const; +  interval operator/(float v) const; +     +  interval& operator+=(float v); +  interval& operator-=(float v); +  interval& operator*=(float v); +  interval& operator/=(float v); + +  //////////////// +  // Inspectors // +  //////////////// +  float lower(void) const; +  float upper(void) const; + +  bool empty(void) const; + +  ////////////// +  // Mutators // +  ////////////// +  void intersect(const interval& i); + +  ///////////// +  // Friends // +  ///////////// +  friend void swap(interval& a, interval& b) { a._swap(b); } + +  friend std::ostream& operator<<(std::ostream& s, const interval& i) +  { +    s << "[" << i.lower() << ", " << i.upper() << "]"; +    return s; +  } + + private: +  ///////////////////// +  // Private Methods // +  ///////////////////// +  void _assign(const interval& i); +  void _swap(interval& i); + +  ////////////////////////// +  // Private Data Members // +  ////////////////////////// +  float _lower, _upper; +}; + +#endif /* _INTERVAL_H_ */ diff --git a/hw3/include/lightSample.h b/hw3/include/lightSample.h new file mode 100644 index 0000000..3dd76b5 --- /dev/null +++ b/hw3/include/lightSample.h @@ -0,0 +1,75 @@ +/******************************************************************/ +/* This file is part of the homework assignments for CSCI-427/527 */ +/* at The College of William & Mary and authored by Pieter Peers. */ +/* No part of this file, whether altered or in original form, can */ +/* be distributed or used outside the context of CSCI-427/527     */ +/* without consent of either the College of William & Mary or     */ +/* Pieter Peers.                                                  */ +/******************************************************************/ +#ifndef _LIGHTSAMPLE_H_ +#define _LIGHTSAMPLE_H_ + +#include "vec3d.h" +#include "color.h" +#include "constants.h" + +class lightSample { + public: +  ////////////////// +  // Constructors // +  ////////////////// +  lightSample(const vec3d& direction=vec3d(0.0f, 0.0f, 0.0f), +	      const color& emittance=color(0.0f, 0.0f, 0.0f), +	      float distance=+LARGE, +	      float pdf=1.0f, +	      float foreshortening=1.0f); + +  lightSample(const lightSample& ls); + +  /////////////// +  // Operators // +  /////////////// +  lightSample& operator=(const lightSample& ls); + +  const color& operator()(void) const; + +  //////////////// +  // Inspectors // +  //////////////// +  const vec3d& directionToPoint(void) const; +  vec3d directionToLight(void) const; +   +  const color& emittance(void) const; +  float distance(void) const; + +  float pdf(void) const; +  float foreshortening(void) const; + +  ///////////// +  // Friends // +  ///////////// +  friend void swap(lightSample& a, lightSample& b) { a._swap(b); } +  friend std::ostream& operator<<(std::ostream& s, const lightSample& ls) +  { +    s << "LightSample: direction=" << ls.directionToPoint() << ", emittance=" << ls() << ", distance=" << ls.distance() << ", pdf=" << ls.pdf() << ", foreshortening=" << ls.foreshortening(); +    return s; +  } + + private: +  ///////////////////// +  // Private Methods // +  ///////////////////// +  void _assign(const lightSample& ls); +  void _swap(lightSample& ls); +   +  ////////////////// +  // Data Members // +  ////////////////// +  vec3d _direction; +  color _emittance; +  float _distance; +  float _pdf; +  float _foreshortening; +}; + +#endif /* _LIGHTSAMPLE_H_ */ diff --git a/hw3/include/lightsource_base.h b/hw3/include/lightsource_base.h new file mode 100644 index 0000000..0a2f0df --- /dev/null +++ b/hw3/include/lightsource_base.h @@ -0,0 +1,51 @@ +/******************************************************************/ +/* This file is part of the homework assignments for CSCI-427/527 */ +/* at The College of William & Mary and authored by Pieter Peers. */ +/* No part of this file, whether altered or in original form, can */ +/* be distributed or used outside the context of CSCI-427/527     */ +/* without consent of either the College of William & Mary or     */ +/* Pieter Peers.                                                  */ +/******************************************************************/ +#ifndef _LIGHTSOURCE_BASE_H_ +#define _LIGHTSOURCE_BASE_H_ + +#include <ostream> + +#include "vec3d.h" +#include "lightSample.h" + +class lightsource_base { + public: +  ////////////////// +  // Constructors // +  ////////////////// +  lightsource_base(void) {} +  lightsource_base(const lightsource_base&) = delete; + +  /////////////// +  // Operators // +  /////////////// +  lightsource_base& operator=(const lightsource_base&) = delete; + +  ///////////// +  // Methods // +  ///////////// +  virtual lightSample intensityAt(const vec3d& point) const = 0; + +  ///////////// +  // Friends // +  ///////////// +  friend std::ostream& operator<<(std::ostream& s, const lightsource_base& lsb) +  { +    lsb._print(s); +    return s; +  } + + private: +  ///////////////////// +  // Private Methods // +  ///////////////////// +  virtual void _print(std::ostream& s) const = 0; +}; + +#endif /* _LIGHTSOURCE_BASE_H_ */ diff --git a/hw3/include/linear_intersector.h b/hw3/include/linear_intersector.h new file mode 100644 index 0000000..221e5fe --- /dev/null +++ b/hw3/include/linear_intersector.h @@ -0,0 +1,62 @@ +/******************************************************************/ +/* This file is part of the homework assignments for CSCI-427/527 */ +/* at The College of William & Mary and authored by Pieter Peers. */ +/* No part of this file, whether altered or in original form, can */ +/* be distributed or used outside the context of CSCI-427/527     */ +/* without consent of either the College of William & Mary or     */ +/* Pieter Peers.                                                  */ +/******************************************************************/ +#ifndef _LINEAR_INTERSECTOR_H_ +#define _LINEAR_INTERSECTOR_H_ + +#include <memory> + +#include "boundedPrimitive.h" +#include "intersector_base.h" +#include "intersector_factory_base.h" + +class linear_intersector : public intersector_base { + public: +  ////////////////// +  // Constructors // +  ////////////////// +  linear_intersector(void); +  linear_intersector(const std::vector<std::shared_ptr<const boundedPrimitive>>& compounds); +  linear_intersector(const linear_intersector&) = delete; + +  /////////////// +  // Operators // +  /////////////// +  linear_intersector& operator=(const linear_intersector&) = delete; +   +  ///////////// +  // Methods // +  ///////////// +  virtual intersectionPoint intersect(const ray& r) const final override; +   + private: +  ////////////////// +  // Data Members // +  ////////////////// +  std::vector<std::shared_ptr<const boundedPrimitive>> _compounds; +}; + + +class linear_intersector_factory : public intersector_factory_base { + public: +  ///////////////// +  // Constructor // +  ///////////////// +  linear_intersector_factory(void) {} + +  /////////////// +  // Operators // +  /////////////// +  std::unique_ptr<const intersector_base> operator()(const boundedCompound& boundedCompound) const final override +  {  +    return std::unique_ptr<const intersector_base>(new linear_intersector(boundedCompound.compounds()));  +  } +}; + +#endif /* _LINEAR_INTERSECTOR_H_ */ + diff --git a/hw3/include/mat3d.h b/hw3/include/mat3d.h new file mode 100644 index 0000000..e70ece4 --- /dev/null +++ b/hw3/include/mat3d.h @@ -0,0 +1,112 @@ +/******************************************************************/ +/* This file is part of the homework assignments for CSCI-427/527 */ +/* at The College of William & Mary and authored by Pieter Peers. */ +/* No part of this file, whether altered or in original form, can */ +/* be distributed or used outside the context of CSCI-427/527     */ +/* without consent of either the College of William & Mary or     */ +/* Pieter Peers.                                                  */ +/******************************************************************/ +#ifndef _MAT3D_H_ +#define _MAT3D_H_ + +#include <array> +#include <ostream> + +#include "vec3d.h" + +class mat3d { + public: +  ///////////// +  // Typedef // +  ///////////// +  typedef float                                      value_type; +  typedef value_type&                                reference; +  typedef const value_type&                          const_reference; +  typedef std::array<value_type,9>::iterator         iterator; +  typedef std::array<value_type,9>::const_iterator   const_iterator; +  typedef std::size_t                                difference; +  typedef std::size_t                                size_type; + +  ///////////////// +  // Constructor // +  ///////////////// +  mat3d(void);                                              // all elements are set to 0 +  explicit mat3d(value_type diag);                          // all elements are set to 0, the diagonal elements are set to 'diag' +  mat3d(const vec3d& X, const vec3d& Y, const vec3d& Z);    // set columns to X, Y, and Z +  mat3d(const mat3d& m);                                    // copy constructor + +  //////////////// +  // Inspectors // +  //////////////// +  static size_type width(void)  { return 3; } +  static size_type height(void) { return 3; } +  static size_type size(void)   { return 9; } + +  iterator begin(void); +  const_iterator begin(void) const; +  iterator end(void); +  const_iterator end(void) const; + +  ////////////// +  // Mutators // +  ////////////// +  void clear(value_type value=0.0f); +  void setDiagonal(value_type value=1.0f); + +  mat3d& transpose(void); + +  /////////////// +  // Operators // +  /////////////// +  mat3d& operator=(const mat3d& m); + +  reference operator()(size_type row, size_type col); +  const_reference operator()(size_type row, size_type col) const; + +  mat3d operator+(const mat3d& m) const; +  mat3d operator-(const mat3d& m) const; +  mat3d operator*(const mat3d& m) const; +  vec3d operator*(const vec3d& v) const; +  mat3d operator*(value_type scale) const; +  mat3d operator/(value_type scale) const; + +  mat3d& operator+=(const mat3d& m); +  mat3d& operator-=(const mat3d& m); +  mat3d& operator*=(const mat3d& m); +  mat3d& operator*=(value_type scale); +  mat3d& operator/=(value_type scale); +   +  ///////////// +  // Friends // +  ///////////// +  friend void swap(mat3d& a, mat3d& b) { a._swap(b); } + +  friend vec3d operator*(const vec3d& v, const mat3d& m)   { return m._premultiply(v); } +  friend mat3d operator*(value_type scale, const mat3d& m) { return (m * scale); } + +  friend mat3d transpose(mat3d& m) { mat3d n(m); return n.transpose(); } + +  friend std::ostream& operator<<(std::ostream& s, const mat3d& m) +  { +    s << "[[" << m(0,0) << ", " << m(0,1) << ", " << m(0,2) << "],["; +    s         << m(1,0) << ", " << m(1,1) << ", " << m(1,2) << "],["; +    s         << m(2,0) << ", " << m(2,1) << ", " << m(2,2) << "]]"; +    return s; +  } +   + private: +  ///////////////////// +  // Private Methods // +  ///////////////////// +  void _swap(mat3d& m); +  void _assign(const mat3d& m); + +  vec3d _premultiply(const vec3d& v) const; + +  ////////////////////////// +  // Private Data Members // +  ////////////////////////// +  std::array<value_type, 9> _data; +}; + +#endif /* _MAT3D_H_ */ diff --git a/hw3/include/phongBrdf.h b/hw3/include/phongBrdf.h new file mode 100644 index 0000000..588efa2 --- /dev/null +++ b/hw3/include/phongBrdf.h @@ -0,0 +1,60 @@ +/******************************************************************/ +/* This file is part of the homework assignments for CSCI-427/527 */ +/* at The College of William & Mary and authored by Pieter Peers. */ +/* No part of this file, whether altered or in original form, can */ +/* be distributed or used outside the context of CSCI-427/527     */ +/* without consent of either the College of William & Mary or     */ +/* Pieter Peers.                                                  */ +/******************************************************************/ +#ifndef _PHONGBRDF_H_ +#define _PHONGBRDF_H_ + +#include "brdf_base.h" + +class phongBrdf : public brdf_base { + public: +  ////////////////// +  // Constructors // +  ////////////////// +  phongBrdf(const color& albedo, float sharpness); +  phongBrdf(const phongBrdf& src); + +  /////////////// +  // Operators // +  /////////////// +  phongBrdf& operator=(const phongBrdf& src); + +  ///////////// +  // Methods // +  ///////////// +  virtual color shade(const vec3d& in, const vec3d& out) const override; + +  virtual bool isSpecular(void) const final override; +  virtual bool isDiffuse(void) const final override; + +  ///////////// +  // Friends // +  ///////////// +  friend void swap(phongBrdf& a, phongBrdf& b) { a._swap(b); } +  friend std::ostream& operator<<(std::ostream& s, const phongBrdf& b) +  { +    b._print(s); +    return s; +  } + + private: +  ///////////////////// +  // Private Methods // +  ///////////////////// +  void _assign(const phongBrdf& src); +  void _swap(phongBrdf& src); +  virtual void _print(std::ostream& s) const override; + +  ////////////////// +  // Data Members // +  ////////////////// +  color _albedo; +  float _sharpness; +}; + +#endif /* _PHONGBRDF_H_ */ diff --git a/hw3/include/phongReflectanceShader.h b/hw3/include/phongReflectanceShader.h new file mode 100644 index 0000000..13291f2 --- /dev/null +++ b/hw3/include/phongReflectanceShader.h @@ -0,0 +1,46 @@ +/******************************************************************/ +/* This file is part of the homework assignments for CSCI-427/527 */ +/* at The College of William & Mary and authored by Pieter Peers. */ +/* No part of this file, whether altered or in original form, can */ +/* be distributed or used outside the context of CSCI-427/527     */ +/* without consent of either the College of William & Mary or     */ +/* Pieter Peers.                                                  */ +/******************************************************************/ +#ifndef _PHONGREFLECTANCESHADER_H_ +#define _PHONGREFLECTANCESHADER_H_ + +#include "phongBrdf.h" +#include "reflectanceParameter.h" +#include "reflectanceShader_base.h" + +class phongReflectanceShader : public reflectanceShader_base { + public: +  ///////////////// +  // Constructor // +  ///////////////// +  phongReflectanceShader(const colorReflectanceParameter& albedo=colorReflectanceParameter(color(1.0f, 1.0f, 1.0f)), const scalarReflectanceParameter& sharpness=20.0f); +  phongReflectanceShader(const phongReflectanceShader& ) = delete; + +  /////////////// +  // Operators // +  /////////////// +  phongReflectanceShader& operator=(const phongReflectanceShader&) = delete; + +protected: +  /////////////////////// +  // Protected Methods // +  /////////////////////// +  virtual void _print(std::ostream& s) const override; + +  virtual std::unique_ptr<const brdf_base> make_brdf(const vec2d& textureCoord) const override; + +private: +  ////////////////// +  // Data Members // +  ////////////////// +  colorReflectanceParameter _albedo; +  scalarReflectanceParameter _sharpness; +}; + +#endif /* _PHONGREFLECTANCESHADER_H_ */ + diff --git a/hw3/include/random_number.h b/hw3/include/random_number.h new file mode 100644 index 0000000..328de25 --- /dev/null +++ b/hw3/include/random_number.h @@ -0,0 +1,50 @@ +/******************************************************************/ +/* This file is part of the homework assignments for CSCI-427/527 */ +/* at The College of William & Mary and authored by Pieter Peers. */ +/* No part of this file, whether altered or in original form, can */ +/* be distributed or used outside the context of CSCI-427/527     */ +/* without consent of either the College of William & Mary or     */ +/* Pieter Peers.                                                  */ +/******************************************************************/ +#ifndef _RANDOM_NUMBER_H_ +#define _RANDOM_NUMBER_H_ + +#include <random> +#include "vec3d.h" +#include "constants.h" +#include "coordinateTransform.h" + +static std::random_device rd; +static std::mt19937 rnd; + +static unsigned int random_int(unsigned int up=std::numeric_limits<unsigned int>::max()) +{ +  std::uniform_int_distribution<unsigned int> dist(0, up); +  return dist(rnd); +} + + +static float random_float(float up=1.0f) +{ +  std::uniform_real_distribution<float> dist(0, up); +  return dist(rnd); +} + + +static vec3d random_direction(const vec3d& normal, float r1=random_float(), float r2=random_float()) +{ +  // generate in standard coordinate system (i.e., Z=(0,0,1)) +  vec3d out(cos(2.0f*PI*r1) * sqrt(std::max(1.0f-r2*r2, 0.0f)), +	    sin(2.0f*PI*r1) * sqrt(std::max(1.0f-r2*r2, 0.0f)), +	    r2); + +  // transform to global coordinates +  coordinateTransformation trans(normal); +  out = trans.transformDirection(out); + +  // Done (PDF = 1/(2.0f*PI)) +  return out; +} + + +#endif /* _RANDOM_NUMBER_H_ */ diff --git a/hw3/include/ray.h b/hw3/include/ray.h new file mode 100644 index 0000000..743375f --- /dev/null +++ b/hw3/include/ray.h @@ -0,0 +1,69 @@ +/******************************************************************/ +/* This file is part of the homework assignments for CSCI-427/527 */ +/* at The College of William & Mary and authored by Pieter Peers. */ +/* No part of this file, whether altered or in original form, can */ +/* be distributed or used outside the context of CSCI-427/527     */ +/* without consent of either the College of William & Mary or     */ +/* Pieter Peers.                                                  */ +/******************************************************************/ +#ifndef _RAY_H_ +#define _RAY_H_ + +#include <ostream> +#include "vec3d.h" +#include "transformation3d.h" + +class ray { + public: +  ////////////////// +  // Constructors // +  ////////////////// +  ray(const vec3d& origin = vec3d(), const vec3d& direction = vec3d()); +  ray(const ray& src); + +  //////////////// +  // Inspectors // +  //////////////// +  const vec3d& origin(void) const    { return _origin; } +  const vec3d& direction(void) const { return _direction; } + +  /////////////// +  // Operators // +  /////////////// +  ray& operator=(const ray& r); +  vec3d operator()(float t) const; +  float operator()(const vec3d& point) const; + +  ////////////// +  // Mutators // +  ////////////// +  ray& transform(const transformation3d& t); +  ray& inverseTransform(const transformation3d& t); + +  ///////////// +  // Friends // +  ///////////// +  friend void swap(ray& a, ray& b)  { a._swap(b); } +  friend ray transform(const ray& r, const transformation3d& t) { return ray(r).transform(t); } +  friend ray inverseTransform(const ray& r, const transformation3d& t) { return ray(r).inverseTransform(t); } +  friend std::ostream& operator<<(std::ostream& s, const ray& r) +  { +    s << r.origin() << "->" << r.direction(); +    return s; +  } + + private: +  ///////////////////// +  // Private Methods // +  ///////////////////// +  void _swap(ray& r); +  void _assign(const ray& r); + +  ////////////////// +  // Data Members // +  ////////////////// +  vec3d _origin; +  vec3d _direction; +}; + +#endif /* _RAY_H_ */ diff --git a/hw3/include/reflectanceParameter.h b/hw3/include/reflectanceParameter.h new file mode 100644 index 0000000..c924653 --- /dev/null +++ b/hw3/include/reflectanceParameter.h @@ -0,0 +1,106 @@ +/******************************************************************/ +/* This file is part of the homework assignments for CSCI-427/527 */ +/* at The College of William & Mary and authored by Pieter Peers. */ +/* No part of this file, whether altered or in original form, can */ +/* be distributed or used outside the context of CSCI-427/527     */ +/* without consent of either the College of William & Mary or     */ +/* Pieter Peers.                                                  */ +/******************************************************************/ +#ifndef _REFLECTANCEPARAMETER_H_ +#define _REFLECTANCEPARAMETER_H_ + +#include <memory> +#include <ostream> + +#include "vec2d.h" +#include "vec3d.h" +#include "color.h" +#include "texture_base.h" + +class scalarReflectanceParameter { + public: +  ///////////////// +  // Constructor // +  ///////////////// +  scalarReflectanceParameter(float value=0.0f); +  scalarReflectanceParameter(const std::shared_ptr<const texture_base>& texture, unsigned int channel=0); +  scalarReflectanceParameter(const scalarReflectanceParameter& src); + +  ////////////// +  // Operator // +  ////////////// +  scalarReflectanceParameter& operator=(const scalarReflectanceParameter& src); + +  float operator()(const vec2d& textureCoord) const; + +  ///////////// +  // Friends // +  ///////////// +  friend void swap(scalarReflectanceParameter& a, scalarReflectanceParameter& b) { a._swap(b); } + +  friend std::ostream& operator<<(std::ostream& s, const scalarReflectanceParameter& param) +  { +    if(param._texture) s << param._texture << "(channel=" << param._channel << ")"; +    else s << param._value; +    return s; +  } + + private: +  ///////////////////// +  // Private Methods // +  ///////////////////// +  void _assign(const scalarReflectanceParameter& src); +  void _swap(scalarReflectanceParameter& swp); + +  ////////////////// +  // Data Members // +  ////////////////// +  float _value; +  unsigned int _channel; +  std::shared_ptr<const texture_base> _texture; +}; + + +class colorReflectanceParameter { + public: +  ///////////////// +  // Constructor // +  ///////////////// +  colorReflectanceParameter(color value=color(0.0f)); +  colorReflectanceParameter(const std::shared_ptr<const texture_base>& texture); +  colorReflectanceParameter(const colorReflectanceParameter& src); + +  ////////////// +  // Operator // +  ////////////// +  colorReflectanceParameter& operator=(const colorReflectanceParameter& src); + +  color operator()(const vec2d& textureCoord) const; + +  ///////////// +  // Friends // +  ///////////// +  friend void swap(colorReflectanceParameter& a, colorReflectanceParameter& b) { a._swap(b); } + +  friend std::ostream& operator<<(std::ostream& s, const colorReflectanceParameter& param) +  { +    if(param._texture) s << param._texture; +    else s << param._value; +    return s; +  } + + private: +  ///////////////////// +  // Private Methods // +  ///////////////////// +  void _assign(const colorReflectanceParameter& src); +  void _swap(colorReflectanceParameter& swp); + +  ////////////////// +  // Data Members // +  ////////////////// +  color _value; +  std::shared_ptr<const texture_base> _texture; +}; + +#endif /* _REFLECTANCEPARAMETER_BASE_H_ */ diff --git a/hw3/include/reflectanceShader_base.h b/hw3/include/reflectanceShader_base.h new file mode 100644 index 0000000..ad91137 --- /dev/null +++ b/hw3/include/reflectanceShader_base.h @@ -0,0 +1,45 @@ +/******************************************************************/ +/* This file is part of the homework assignments for CSCI-427/527 */ +/* at The College of William & Mary and authored by Pieter Peers. */ +/* No part of this file, whether altered or in original form, can */ +/* be distributed or used outside the context of CSCI-427/527     */ +/* without consent of either the College of William & Mary or     */ +/* Pieter Peers.                                                  */ +/******************************************************************/ +#ifndef _REFLECTANCESHADER_BASE_H_ +#define _REFLECTANCESHADER_BASE_H_ + +#include <memory> +#include "brdf_base.h" +#include "shader_base.h" + +class reflectanceShader_base : public shader_base { + public: +  ////////////////// +  // Constructors // +  ////////////////// +  reflectanceShader_base(void) {} +  reflectanceShader_base(const reflectanceShader_base&) = delete; + +  /////////////// +  // Operators // +  /////////////// +  reflectanceShader_base& operator=(const reflectanceShader_base&) = delete; + +  ///////////// +  // Methods // +  ///////////// +  virtual color shade(const intersectionPoint& ip, const vec3d& light_dir) const final override; + +  virtual shaderProperties properties(const intersectionPoint& ip) const final override; + + protected: +  /////////////////////// +  // Protected Methods // +  /////////////////////// +  virtual void _print(std::ostream& s) const = 0; + +  virtual std::unique_ptr<const brdf_base> make_brdf(const vec2d& textureCoord) const = 0; +}; + +#endif /* _REFLECTANCE_SHADER_BASE_H_ */ diff --git a/hw3/include/scene.h b/hw3/include/scene.h new file mode 100644 index 0000000..ee3e416 --- /dev/null +++ b/hw3/include/scene.h @@ -0,0 +1,59 @@ +/******************************************************************/ +/* This file is part of the homework assignments for CSCI-427/527 */ +/* at The College of William & Mary and authored by Pieter Peers. */ +/* No part of this file, whether altered or in original form, can */ +/* be distributed or used outside the context of CSCI-427/527     */ +/* without consent of either the College of William & Mary or     */ +/* Pieter Peers.                                                  */ +/******************************************************************/ +#ifndef _SCENE_H_ +#define _SCENE_H_ + +#include <vector> +#include <string> +#include <memory> + +#include "ray.h" +#include "image.h" +#include "camera.h" +#include "boundedCompound.h" +#include "lightsource_base.h" +#include "intersectionPoint.h" + +class scene { +  friend void importScene(const std::string&, scene&); + public: +  ////////////////// +  // Constructors // +  ////////////////// +  scene(void) {} +  scene(const scene&) = delete; + +  /////////////// +  // Operators // +  /////////////// +  camera& operator=(const camera&) = delete; + +  //////////////// +  // Inspectors // +  //////////////// +  const camera& getCamera(void) const; + +  const lightsource_base& getLightsource(size_t idx) const; +  size_t numberOfLightsources(void) const; + +  ///////////// +  // Methods // +  ///////////// +  intersectionPoint intersect(const ray& r) const; + + private: +  ////////////////// +  // Data Members // +  ////////////////// +  camera _camera; +  std::unique_ptr<const boundedCompound> _sceneGraphRoot; +  std::vector<std::shared_ptr<const lightsource_base>> _lightsources; +}; + +#endif /* _SCENE_H_ */ diff --git a/hw3/include/sceneGraphNode.h b/hw3/include/sceneGraphNode.h new file mode 100644 index 0000000..38e7de1 --- /dev/null +++ b/hw3/include/sceneGraphNode.h @@ -0,0 +1,45 @@ +/******************************************************************/ +/* This file is part of the homework assignments for CSCI-427/527 */ +/* at The College of William & Mary and authored by Pieter Peers. */ +/* No part of this file, whether altered or in original form, can */ +/* be distributed or used outside the context of CSCI-427/527     */ +/* without consent of either the College of William & Mary or     */ +/* Pieter Peers.                                                  */ +/******************************************************************/ +#ifndef _SCENEGRAPHNODE_H_ +#define _SCENEGRAPHNODE_H_ + +#include <vector> +#include <memory> + +#include "shader_base.h" +#include "boundedCompound.h" +#include "transformation3d.h" + +class sceneGraphNode : public boundedCompound { + public: +  ////////////////// +  // Constructors // +  ////////////////// +  sceneGraphNode(void); +  sceneGraphNode(const std::vector<std::shared_ptr<const boundedPrimitive>>& nodes, const transformation3d& transform=transformation3d(), const std::shared_ptr<const shader_base>& shader=nullptr); +  sceneGraphNode(const sceneGraphNode&) = delete; + +  /////////////// +  // Operators // +  /////////////// +  sceneGraphNode& operator=(sceneGraphNode&) = delete; + +  ///////////// +  // Methods // +  ///////////// +  virtual const std::vector<std::shared_ptr<const boundedPrimitive>>& compounds(void) const final override; + + private: +  ////////////////// +  // Data Members // +  ////////////////// +  std::vector<std::shared_ptr<const boundedPrimitive>> _nodes; +}; + +#endif /* _SCENEGRAPHNODE_H_ */ diff --git a/hw3/include/sceneIO.h b/hw3/include/sceneIO.h new file mode 100644 index 0000000..59fc6cd --- /dev/null +++ b/hw3/include/sceneIO.h @@ -0,0 +1,17 @@ +/******************************************************************/ +/* This file is part of the homework assignments for CSCI-427/527 */ +/* at The College of William & Mary and authored by Pieter Peers. */ +/* No part of this file, whether altered or in original form, can */ +/* be distributed or used outside the context of CSCI-427/527     */ +/* without consent of either the College of William & Mary or     */ +/* Pieter Peers.                                                  */ +/******************************************************************/ +#ifndef _SCENE_IO_H_ +#define _SCENE_IO_H_ + +#include <string> +#include "scene.h" + +void importScene(const std::string& filename, scene& s); + +#endif /* _SCENE_IO_H_ */ diff --git a/hw3/include/sceneIO_basis.h b/hw3/include/sceneIO_basis.h new file mode 100644 index 0000000..5f67172 --- /dev/null +++ b/hw3/include/sceneIO_basis.h @@ -0,0 +1,22 @@ +/******************************************************************/ +/* This file is part of the homework assignments for CSCI-427/527 */ +/* at The College of William & Mary and authored by Pieter Peers. */ +/* No part of this file, whether altered or in original form, can */ +/* be distributed or used outside the context of CSCI-427/527     */ +/* without consent of either the College of William & Mary or     */ +/* Pieter Peers.                                                  */ +/******************************************************************/ +#ifndef _SCENEIO_BASIS_H_ +#define _SCENEIO_BASIS_H_ + +#include <string> +#include <vector> +#include <memory> + +#include "camera.h" +#include "intersector_factory_base.h" + +bool importCamera(const XMLNode& node, camera& cam); +void importIntersector(const XMLNode& node, std::unique_ptr<const intersector_factory_base>& intersector); + +#endif /* _SCENEIO_BASIS_H_ */ diff --git a/hw3/include/sceneIO_cache.h b/hw3/include/sceneIO_cache.h new file mode 100644 index 0000000..3807c86 --- /dev/null +++ b/hw3/include/sceneIO_cache.h @@ -0,0 +1,52 @@ +/******************************************************************/ +/* This file is part of the homework assignments for CSCI-427/527 */ +/* at The College of William & Mary and authored by Pieter Peers. */ +/* No part of this file, whether altered or in original form, can */ +/* be distributed or used outside the context of CSCI-427/527     */ +/* without consent of either the College of William & Mary or     */ +/* Pieter Peers.                                                  */ +/******************************************************************/ +#ifndef _SCENEIO_CACHE_H_ +#define _SCENEIO_CACHE_H_ + +#include <map> +#include <memory> +#include <string> +#include <vector> + +template<typename T> +class nodeCache { + public: +  ////////////////// +  // Constructors // +  ////////////////// +  nodeCache(void) {} +  nodeCache(const nodeCache<T>&) = delete; + +  /////////////// +  // Operators // +  /////////////// +  nodeCache& operator=(const nodeCache& ) = delete; + +  ///////////// +  // Methods // +  ///////////// +  std::shared_ptr<T> get(const std::string& name) const; +  bool add(const std::string& name, const std::shared_ptr<T>& node); + +  std::vector<std::shared_ptr<T>> unusedNodes(unsigned int maxCount=1) const; +  std::vector<std::shared_ptr<T>> allNodes(void) const; + + private: +  ////////////////////////// +  // Private Data Members // +  ////////////////////////// +  std::map<std::string, std::shared_ptr<T>> _cache; +}; + +//////////////////// +// Inline Methods // +//////////////////// +#include "sceneIO_cache.inline.h" + +#endif /* _SCENEIO_CACHE_H_ */ diff --git a/hw3/include/sceneIO_cache.inline.h b/hw3/include/sceneIO_cache.inline.h new file mode 100644 index 0000000..27d9cf0 --- /dev/null +++ b/hw3/include/sceneIO_cache.inline.h @@ -0,0 +1,66 @@ +/******************************************************************/ +/* This file is part of the homework assignments for CSCI-427/527 */ +/* at The College of William & Mary and authored by Pieter Peers. */ +/* No part of this file, whether altered or in original form, can */ +/* be distributed or used outside the context of CSCI-427/527     */ +/* without consent of either the College of William & Mary or     */ +/* Pieter Peers.                                                  */ +/******************************************************************/ +#if defined(_SCENEIO_CACHE_H_) && !defined(_SCENEIO_CACHE_INLINE_H_) +#define _SCENEIO_CACHE_INLINE_H_ + +#include <string> +#include <memory> +#include <vector> + +#include "errorMessage.h" + +template<typename T> +std::shared_ptr<T> nodeCache<T>::get(const std::string& name) const +{ +  // see if node exists +  auto ref_node = _cache.find(name); + +  // return nullptr if not. +  if(ref_node == _cache.end()) return nullptr; + +  // return node. +  else return ref_node->second; +} + + +template<typename T> +bool nodeCache<T>::add(const std::string& name, const std::shared_ptr<T>& node) +{ +  _cache[name] = node; +} + +template<typename T> +std::vector<std::shared_ptr<T>> nodeCache<T>::unusedNodes(unsigned int maxCount) const +{ +  std::vector<std::shared_ptr<T>> result; + +  // check each node if unique +  for(auto itr=_cache.begin(); itr != _cache.end(); itr++) +    if(itr->second.use_count() <= maxCount) +      result.push_back(itr->second); + +  // done. +  return result; +} + + +template<typename T> +std::vector<std::shared_ptr<T>> nodeCache<T>::allNodes(void) const +{ +  std::vector<std::shared_ptr<T>> result; + +  // check each node if unique +  for(auto itr=_cache.begin(); itr != _cache.end(); itr++) +      result.push_back(itr->second); + +  // done. +  return result; +} + +#endif /* _SCENEIO_CACHE_INLINE_H_ */ diff --git a/hw3/include/sceneIO_core.h b/hw3/include/sceneIO_core.h new file mode 100644 index 0000000..8aa726a --- /dev/null +++ b/hw3/include/sceneIO_core.h @@ -0,0 +1,24 @@ +/******************************************************************/ +/* This file is part of the homework assignments for CSCI-427/527 */ +/* at The College of William & Mary and authored by Pieter Peers. */ +/* No part of this file, whether altered or in original form, can */ +/* be distributed or used outside the context of CSCI-427/527     */ +/* without consent of either the College of William & Mary or     */ +/* Pieter Peers.                                                  */ +/******************************************************************/ +#ifndef _SCENEIO_CORE_H_ +#define _SCENEIO_CORE_H_ + +#include "sceneIO_xml.h" +#include "color.h" +#include "vec2d.h" +#include "vec3d.h" + +color getColor(const XMLNode& node, const std::string& name, const color& default_value=color()); +vec3d getVec3d(const XMLNode& node, const std::string& name, const vec3d& default_value=vec3d()); +vec2d getVec2d(const XMLNode& node, const std::string& name, const vec2d& default_value=vec2d()); +std::string getString(const XMLNode& node, const std::string& name, const std::string& default_value=std::string("")); +float getFloat(const XMLNode& node, const std::string& name, float default_value=0.0f); +unsigned int getInteger(const XMLNode& node, const std::string& name, unsigned int default_value=0); + +#endif /* _SCENEIO_CORE_H_ */ diff --git a/hw3/include/sceneIO_geometry.h b/hw3/include/sceneIO_geometry.h new file mode 100644 index 0000000..fc4d80b --- /dev/null +++ b/hw3/include/sceneIO_geometry.h @@ -0,0 +1,23 @@ +/******************************************************************/ +/* This file is part of the homework assignments for CSCI-427/527 */ +/* at The College of William & Mary and authored by Pieter Peers. */ +/* No part of this file, whether altered or in original form, can */ +/* be distributed or used outside the context of CSCI-427/527     */ +/* without consent of either the College of William & Mary or     */ +/* Pieter Peers.                                                  */ +/******************************************************************/ +#ifndef _SCENEIO_GEOMETRY_H_ +#define _SCENEIO_GEOMETRY_H_ + +#include <memory> + +#include "sceneIO_xml.h" +#include "sceneIO_cache.h" + +#include "shader_base.h" +#include "texture_base.h" +#include "boundedPrimitive.h" + +std::shared_ptr<boundedPrimitive> importGeometry(const XMLNode& node, nodeCache<boundedPrimitive>& shape_cache, nodeCache<shader_base>& shader_cache, nodeCache<texture_base>& texture_cache, const std::string& rootDir); + +#endif /* _SCENEIO_GEOMETRY_H_ */ diff --git a/hw3/include/sceneIO_light.h b/hw3/include/sceneIO_light.h new file mode 100644 index 0000000..e2745a2 --- /dev/null +++ b/hw3/include/sceneIO_light.h @@ -0,0 +1,25 @@ +/******************************************************************/ +/* This file is part of the homework assignments for CSCI-427/527 */ +/* at The College of William & Mary and authored by Pieter Peers. */ +/* No part of this file, whether altered or in original form, can */ +/* be distributed or used outside the context of CSCI-427/527     */ +/* without consent of either the College of William & Mary or     */ +/* Pieter Peers.                                                  */ +/******************************************************************/ +#ifndef _SCENEIO_LIGHT_H_ +#define _SCENEIO_LIGHT_H_ + +#include <memory> + +#include "sceneIO_xml.h" +#include "sceneIO_cache.h" + +#include "shader_base.h" +#include "texture_base.h" +#include "boundedPrimitive.h" + +#include "lightsource_base.h" + +std::shared_ptr<const lightsource_base> importLight(const XMLNode& node, nodeCache<boundedPrimitive>& shape_cache, nodeCache<shader_base>& shader_cache, nodeCache<texture_base>& texture_cache, const std::string& rootDir); + +#endif /* _SCENEIO_LIGHT_H_ */ diff --git a/hw3/include/sceneIO_material.h b/hw3/include/sceneIO_material.h new file mode 100644 index 0000000..9c0852b --- /dev/null +++ b/hw3/include/sceneIO_material.h @@ -0,0 +1,22 @@ +/******************************************************************/ +/* This file is part of the homework assignments for CSCI-427/527 */ +/* at The College of William & Mary and authored by Pieter Peers. */ +/* No part of this file, whether altered or in original form, can */ +/* be distributed or used outside the context of CSCI-427/527     */ +/* without consent of either the College of William & Mary or     */ +/* Pieter Peers.                                                  */ +/******************************************************************/ +#ifndef _SCENEIO_MATERIAL_H_ +#define _SCENEIO_MATERIAL_H_ + +#include <memory> + +#include "sceneIO_xml.h" +#include "sceneIO_cache.h" + +#include "shader_base.h" +#include "texture_base.h" + +std::shared_ptr<shader_base> importMaterial(const XMLNode& node, nodeCache<shader_base>& shader_cache, nodeCache<texture_base>& texture_cache, const std::string& rootDir); + +#endif /* _SCENEIO_MATERIAL_H_ */ diff --git a/hw3/include/sceneIO_xml.h b/hw3/include/sceneIO_xml.h new file mode 100644 index 0000000..5df35a2 --- /dev/null +++ b/hw3/include/sceneIO_xml.h @@ -0,0 +1,51 @@ +/******************************************************************/ +/* This file is part of the homework assignments for CSCI-427/527 */ +/* at The College of William & Mary and authored by Pieter Peers. */ +/* No part of this file, whether altered or in original form, can */ +/* be distributed or used outside the context of CSCI-427/527     */ +/* without consent of either the College of William & Mary or     */ +/* Pieter Peers.                                                  */ +/******************************************************************/ +#ifndef _SCENEIO_XML_H_ +#define _SCENEIO_XML_H_ + +#include <memory> +#include <string> +#include "tinyxml2.h" + +class XMLNode { + public: +  ///////////////// +  // Constructor // +  ///////////////// +  XMLNode(const std::string& filename); +  XMLNode(const tinyxml2::XMLElement* element, const std::shared_ptr<tinyxml2::XMLDocument>& xml); +  XMLNode(const XMLNode& node); + +  ///////////// +  // Methods // +  ///////////// +  XMLNode firstChild(void) const; +  XMLNode findChild(const std::string& name) const; + +  bool isValid(void) const; +  std::string name(void) const; +  std::string attribute(const std::string& attribute) const; + +  /////////////// +  // Operators // +  /////////////// +  XMLNode& operator++(void); +  XMLNode& operator++(int); +  XMLNode& operator=(const XMLNode& src); + + protected: +  ////////////////// +  // Data Members // +  ////////////////// +  const tinyxml2::XMLElement* _element; +  std::shared_ptr<tinyxml2::XMLDocument> _xml; +}; + + +#endif /* _SCENEIO_XML_H_ */ diff --git a/hw3/include/shaderProperties.h b/hw3/include/shaderProperties.h new file mode 100644 index 0000000..859aaac --- /dev/null +++ b/hw3/include/shaderProperties.h @@ -0,0 +1,38 @@ +/******************************************************************/ +/* This file is part of the homework assignments for CSCI-427/527 */ +/* at The College of William & Mary and authored by Pieter Peers. */ +/* No part of this file, whether altered or in original form, can */ +/* be distributed or used outside the context of CSCI-427/527     */ +/* without consent of either the College of William & Mary or     */ +/* Pieter Peers.                                                  */ +/******************************************************************/ +#ifndef _SHADERPROPERTIES_H_ +#define _SHADERPROPERTIES_H_ + +class shaderProperties { + public: +  ///////////////// +  // Constructor // +  ///////////////// +  shaderProperties(bool diff=true, bool spec=true) : diffuse(diff), specular(spec) {} + +  ////////////// +  // Operator // +  ////////////// +  bool operator==(const shaderProperties& sp) const; +  bool operator!=(const shaderProperties& sp) const; + +  shaderProperties& operator&=(const shaderProperties& sp); +  shaderProperties& operator|=(const shaderProperties& sp); +  shaderProperties& operator~(void); + +  shaderProperties operator&(const shaderProperties& sp) const; +  shaderProperties operator|(const shaderProperties& sp) const; + +  ///////////////////////// +  // Public data members // +  ///////////////////////// +  bool diffuse, specular; +}; + +#endif /* _SHADERPROPERTIES_H_ */ diff --git a/hw3/include/shader_base.h b/hw3/include/shader_base.h new file mode 100644 index 0000000..b96cc33 --- /dev/null +++ b/hw3/include/shader_base.h @@ -0,0 +1,59 @@ +/******************************************************************/ +/* This file is part of the homework assignments for CSCI-427/527 */ +/* at The College of William & Mary and authored by Pieter Peers. */ +/* No part of this file, whether altered or in original form, can */ +/* be distributed or used outside the context of CSCI-427/527     */ +/* without consent of either the College of William & Mary or     */ +/* Pieter Peers.                                                  */ +/******************************************************************/ +#ifndef _SHADER_BASE_H_ +#define _SHADER_BASE_H_ + +#include <memory> +#include <ostream> + +#include "vec2d.h" +#include "vec3d.h" +#include "color.h" +#include "shaderProperties.h" +#include "intersectionPoint.h" + + +class shader_base  +{ + public: +  ////////////////// +  // Constructors // +  ////////////////// +  shader_base(void) {} +  shader_base(const shader_base&) = delete; + +  /////////////// +  // Operators // +  /////////////// +  shader_base& operator=(const shader_base&) = delete; + +  ///////////// +  // Methods // +  ///////////// +  virtual color shade(const intersectionPoint& ip, const vec3d& light_dir) const = 0; + +  virtual shaderProperties properties(const intersectionPoint& ip) const = 0; + +  ///////////// +  // Friends // +  ///////////// +  friend std::ostream& operator<<(std::ostream& s, const shader_base& shader) +  { +    shader._print(s); +    return s; +  } + + protected: +  /////////////////////// +  // Protected Methods // +  /////////////////////// +  virtual void _print(std::ostream& s) const = 0; +}; + +#endif /* _SHADER_BASE_H_ */ diff --git a/hw3/include/shadingFrameTransformation.h b/hw3/include/shadingFrameTransformation.h new file mode 100644 index 0000000..2d8bd34 --- /dev/null +++ b/hw3/include/shadingFrameTransformation.h @@ -0,0 +1,57 @@ +/******************************************************************/ +/* This file is part of the homework assignments for CSCI-427/527 */ +/* at The College of William & Mary and authored by Pieter Peers. */ +/* No part of this file, whether altered or in original form, can */ +/* be distributed or used outside the context of CSCI-427/527     */ +/* without consent of either the College of William & Mary or     */ +/* Pieter Peers.                                                  */ +/******************************************************************/ +#ifndef _SHADINGFRAMETRANSFORMATION_H_ +#define _SHADINGFRAMETRANSFORMATION_H_ + +#include <memory> + +#include "vec2d.h" +#include "shader_base.h" +#include "transformation3d.h" + +class shadingFrameTransformation : public shader_base { + public: +  ////////////////// +  // Constructors // +  ////////////////// +  shadingFrameTransformation(const std::shared_ptr<const shader_base>& shader); +  shadingFrameTransformation(const shadingFrameTransformation&) = delete; + +  /////////////// +  // Operators // +  /////////////// +  shadingFrameTransformation& operator=(const shadingFrameTransformation&) = delete; + +  ///////////// +  // Methods // +  ///////////// +  virtual color shade(const intersectionPoint& ip, const vec3d& light_dir) const final override; + +  virtual color reflectance(const intersectionPoint& ip, const vec3d& light_dir, const shaderProperties& properties=shaderProperties()) const final override; +  virtual brdfSample sample(const intersectionPoint& ip, float r1, float r2, const shaderProperties& properties=shaderProperties()) const final override; +  virtual float reflectivity(const intersectionPoint& ip, const shaderProperties& properties=shaderProperties()) const final override; +  virtual color emittance(const intersectionPoint& ip) const final override; + +  virtual shaderProperties properties(const intersectionPoint& ip) const final override; + + + protected: +  /////////////////////// +  // Protected Methods // +  /////////////////////// +  virtual transformation3d _transformation(const vec2d& textureCoord) const = 0; +  virtual void _print(std::ostream& s) const = 0; + +  ////////////////// +  // Data Members // +  ////////////////// +  std::shared_ptr<const shader_base> _shader; +}; + +#endif /* _SHADINGFRAMETRANSFORMATION_H_ */ diff --git a/hw3/include/texture_base.h b/hw3/include/texture_base.h new file mode 100644 index 0000000..919ab53 --- /dev/null +++ b/hw3/include/texture_base.h @@ -0,0 +1,67 @@ +/******************************************************************/ +/* This file is part of the homework assignments for CSCI-427/527 */ +/* at The College of William & Mary and authored by Pieter Peers. */ +/* No part of this file, whether altered or in original form, can */ +/* be distributed or used outside the context of CSCI-427/527     */ +/* without consent of either the College of William & Mary or     */ +/* Pieter Peers.                                                  */ +/******************************************************************/ +#ifndef _TEXTURE_BASE_H_ +#define _TEXTURE_BASE_H_ + +#include "vec2d.h" +#include "image.h" + +class texture_base : public image { + public: +  ////////////////// +  // Constructors // +  ////////////////// +  texture_base(bool repeat=true); +  texture_base(const texture_base& src); + +  /////////////// +  // Operators // +  /////////////// +  texture_base& operator=(const texture_base& src); + +  virtual image::value_type operator()(const vec2d& textureCoord) const = 0; + +  //////////////// +  // Inspectors // +  //////////////// +  bool repeatEdge(void) const { return _repeat; } +  bool wrapEdge(void) const { return !_repeat; } + +  ///////////// +  // Friends // +  ///////////// +  friend void swap(texture_base& a, texture_base& b) { a._swap(b); } + +  friend std::ostream& operator<<(std::ostream& s, const texture_base& t) +  { +    t._print(s); +    return s; +  } + + protected: +  /////////////////////// +  // Protected Methods // +  /////////////////////// +  virtual void _assign(const texture_base& src); +  color& _at(signed int x, signed int y); +  const color& _at(signed int x, signed int y) const; + + private: +  ///////////////////// +  // Private Methods // +  ///////////////////// +  virtual void _print(std::ostream& s) const=0; + +  ////////////////// +  // Data Members // +  ////////////////// +  bool _repeat; +}; + +#endif /* _TEXTURE_BASE_H_ */ diff --git a/hw3/include/tinyxml2.h b/hw3/include/tinyxml2.h new file mode 100644 index 0000000..fb7464a --- /dev/null +++ b/hw3/include/tinyxml2.h @@ -0,0 +1,2102 @@ +/*
 +Original code by Lee Thomason (www.grinninglizard.com)
 +
 +This software is provided 'as-is', without any express or implied
 +warranty. In no event will the authors be held liable for any
 +damages arising from the use of this software.
 +
 +Permission is granted to anyone to use this software for any
 +purpose, including commercial applications, and to alter it and
 +redistribute it freely, subject to the following restrictions:
 +
 +1. The origin of this software must not be misrepresented; you must
 +not claim that you wrote the original software. If you use this
 +software in a product, an acknowledgment in the product documentation
 +would be appreciated but is not required.
 +
 +2. Altered source versions must be plainly marked as such, and
 +must not be misrepresented as being the original software.
 +
 +3. This notice may not be removed or altered from any source
 +distribution.
 +*/
 +
 +#ifndef TINYXML2_INCLUDED
 +#define TINYXML2_INCLUDED
 +
 +#if defined(ANDROID_NDK) || defined(__BORLANDC__) || defined(__QNXNTO__)
 +#   include <ctype.h>
 +#   include <limits.h>
 +#   include <stdio.h>
 +#   include <stdlib.h>
 +#   include <string.h>
 +#else
 +#   include <cctype>
 +#   include <climits>
 +#   include <cstdio>
 +#   include <cstdlib>
 +#   include <cstring>
 +#endif
 +
 +/*
 +   TODO: intern strings instead of allocation.
 +*/
 +/*
 +	gcc:
 +        g++ -Wall -DDEBUG tinyxml2.cpp xmltest.cpp -o gccxmltest.exe
 +
 +    Formatting, Artistic Style:
 +        AStyle.exe --style=1tbs --indent-switches --break-closing-brackets --indent-preprocessor tinyxml2.cpp tinyxml2.h
 +*/
 +
 +#if defined( _DEBUG ) || defined( DEBUG ) || defined (__DEBUG__)
 +#   ifndef DEBUG
 +#       define DEBUG
 +#   endif
 +#endif
 +
 +#ifdef _MSC_VER
 +#   pragma warning(push)
 +#   pragma warning(disable: 4251)
 +#endif
 +
 +#ifdef _WIN32
 +#   ifdef TINYXML2_EXPORT
 +#       define TINYXML2_LIB __declspec(dllexport)
 +#   elif defined(TINYXML2_IMPORT)
 +#       define TINYXML2_LIB __declspec(dllimport)
 +#   else
 +#       define TINYXML2_LIB
 +#   endif
 +#else
 +#   define TINYXML2_LIB
 +#endif
 +
 +
 +#if defined(DEBUG)
 +#   if defined(_MSC_VER)
 +#       // "(void)0," is for suppressing C4127 warning in "assert(false)", "assert(true)" and the like
 +#       define TIXMLASSERT( x )           if ( !((void)0,(x))) { __debugbreak(); }
 +#   elif defined (ANDROID_NDK)
 +#       include <android/log.h>
 +#       define TIXMLASSERT( x )           if ( !(x)) { __android_log_assert( "assert", "grinliz", "ASSERT in '%s' at %d.", __FILE__, __LINE__ ); }
 +#   else
 +#       include <assert.h>
 +#       define TIXMLASSERT                assert
 +#   endif
 +#else
 +#   define TIXMLASSERT( x )               {}
 +#endif
 +
 +
 +/* Versioning, past 1.0.14:
 +	http://semver.org/
 +*/
 +static const int TIXML2_MAJOR_VERSION = 3;
 +static const int TIXML2_MINOR_VERSION = 0;
 +static const int TIXML2_PATCH_VERSION = 0;
 +
 +namespace tinyxml2
 +{
 +class XMLDocument;
 +class XMLElement;
 +class XMLAttribute;
 +class XMLComment;
 +class XMLText;
 +class XMLDeclaration;
 +class XMLUnknown;
 +class XMLPrinter;
 +
 +/*
 +	A class that wraps strings. Normally stores the start and end
 +	pointers into the XML file itself, and will apply normalization
 +	and entity translation if actually read. Can also store (and memory
 +	manage) a traditional char[]
 +*/
 +class StrPair
 +{
 +public:
 +    enum {
 +        NEEDS_ENTITY_PROCESSING			= 0x01,
 +        NEEDS_NEWLINE_NORMALIZATION		= 0x02,
 +        NEEDS_WHITESPACE_COLLAPSING     = 0x04,
 +
 +        TEXT_ELEMENT		            	= NEEDS_ENTITY_PROCESSING | NEEDS_NEWLINE_NORMALIZATION,
 +        TEXT_ELEMENT_LEAVE_ENTITIES		= NEEDS_NEWLINE_NORMALIZATION,
 +        ATTRIBUTE_NAME		            	= 0,
 +        ATTRIBUTE_VALUE		            	= NEEDS_ENTITY_PROCESSING | NEEDS_NEWLINE_NORMALIZATION,
 +        ATTRIBUTE_VALUE_LEAVE_ENTITIES  	= NEEDS_NEWLINE_NORMALIZATION,
 +        COMMENT				        = NEEDS_NEWLINE_NORMALIZATION
 +    };
 +
 +    StrPair() : _flags( 0 ), _start( 0 ), _end( 0 ) {}
 +    ~StrPair();
 +
 +    void Set( char* start, char* end, int flags ) {
 +        Reset();
 +        _start  = start;
 +        _end    = end;
 +        _flags  = flags | NEEDS_FLUSH;
 +    }
 +
 +    const char* GetStr();
 +
 +    bool Empty() const {
 +        return _start == _end;
 +    }
 +
 +    void SetInternedStr( const char* str ) {
 +        Reset();
 +        _start = const_cast<char*>(str);
 +    }
 +
 +    void SetStr( const char* str, int flags=0 );
 +
 +    char* ParseText( char* in, const char* endTag, int strFlags );
 +    char* ParseName( char* in );
 +
 +    void TransferTo( StrPair* other );
 +
 +private:
 +    void Reset();
 +    void CollapseWhitespace();
 +
 +    enum {
 +        NEEDS_FLUSH = 0x100,
 +        NEEDS_DELETE = 0x200
 +    };
 +
 +    int     _flags;
 +    char*   _start;
 +    char*   _end;
 +
 +    StrPair( const StrPair& other );	// not supported
 +    void operator=( StrPair& other );	// not supported, use TransferTo()
 +};
 +
 +
 +/*
 +	A dynamic array of Plain Old Data. Doesn't support constructors, etc.
 +	Has a small initial memory pool, so that low or no usage will not
 +	cause a call to new/delete
 +*/
 +template <class T, int INITIAL_SIZE>
 +class DynArray
 +{
 +public:
 +    DynArray() {
 +        _mem = _pool;
 +        _allocated = INITIAL_SIZE;
 +        _size = 0;
 +    }
 +
 +    ~DynArray() {
 +        if ( _mem != _pool ) {
 +            delete [] _mem;
 +        }
 +    }
 +
 +    void Clear() {
 +        _size = 0;
 +    }
 +
 +    void Push( T t ) {
 +        TIXMLASSERT( _size < INT_MAX );
 +        EnsureCapacity( _size+1 );
 +        _mem[_size++] = t;
 +    }
 +
 +    T* PushArr( int count ) {
 +        TIXMLASSERT( count >= 0 );
 +        TIXMLASSERT( _size <= INT_MAX - count );
 +        EnsureCapacity( _size+count );
 +        T* ret = &_mem[_size];
 +        _size += count;
 +        return ret;
 +    }
 +
 +    T Pop() {
 +        TIXMLASSERT( _size > 0 );
 +        return _mem[--_size];
 +    }
 +
 +    void PopArr( int count ) {
 +        TIXMLASSERT( _size >= count );
 +        _size -= count;
 +    }
 +
 +    bool Empty() const					{
 +        return _size == 0;
 +    }
 +
 +    T& operator[](int i)				{
 +        TIXMLASSERT( i>= 0 && i < _size );
 +        return _mem[i];
 +    }
 +
 +    const T& operator[](int i) const	{
 +        TIXMLASSERT( i>= 0 && i < _size );
 +        return _mem[i];
 +    }
 +
 +    const T& PeekTop() const            {
 +        TIXMLASSERT( _size > 0 );
 +        return _mem[ _size - 1];
 +    }
 +
 +    int Size() const					{
 +        TIXMLASSERT( _size >= 0 );
 +        return _size;
 +    }
 +
 +    int Capacity() const				{
 +        TIXMLASSERT( _allocated >= INITIAL_SIZE );
 +        return _allocated;
 +    }
 +
 +    const T* Mem() const				{
 +        TIXMLASSERT( _mem );
 +        return _mem;
 +    }
 +
 +    T* Mem()							{
 +        TIXMLASSERT( _mem );
 +        return _mem;
 +    }
 +
 +private:
 +    DynArray( const DynArray& ); // not supported
 +    void operator=( const DynArray& ); // not supported
 +
 +    void EnsureCapacity( int cap ) {
 +        TIXMLASSERT( cap > 0 );
 +        if ( cap > _allocated ) {
 +            TIXMLASSERT( cap <= INT_MAX / 2 );
 +            int newAllocated = cap * 2;
 +            T* newMem = new T[newAllocated];
 +            memcpy( newMem, _mem, sizeof(T)*_size );	// warning: not using constructors, only works for PODs
 +            if ( _mem != _pool ) {
 +                delete [] _mem;
 +            }
 +            _mem = newMem;
 +            _allocated = newAllocated;
 +        }
 +    }
 +
 +    T*  _mem;
 +    T   _pool[INITIAL_SIZE];
 +    int _allocated;		// objects allocated
 +    int _size;			// number objects in use
 +};
 +
 +
 +/*
 +	Parent virtual class of a pool for fast allocation
 +	and deallocation of objects.
 +*/
 +class MemPool
 +{
 +public:
 +    MemPool() {}
 +    virtual ~MemPool() {}
 +
 +    virtual int ItemSize() const = 0;
 +    virtual void* Alloc() = 0;
 +    virtual void Free( void* ) = 0;
 +    virtual void SetTracked() = 0;
 +    virtual void Clear() = 0;
 +};
 +
 +
 +/*
 +	Template child class to create pools of the correct type.
 +*/
 +template< int SIZE >
 +class MemPoolT : public MemPool
 +{
 +public:
 +    MemPoolT() : _root(0), _currentAllocs(0), _nAllocs(0), _maxAllocs(0), _nUntracked(0)	{}
 +    ~MemPoolT() {
 +        Clear();
 +    }
 +    
 +    void Clear() {
 +        // Delete the blocks.
 +        while( !_blockPtrs.Empty()) {
 +            Block* b  = _blockPtrs.Pop();
 +            delete b;
 +        }
 +        _root = 0;
 +        _currentAllocs = 0;
 +        _nAllocs = 0;
 +        _maxAllocs = 0;
 +        _nUntracked = 0;
 +    }
 +
 +    virtual int ItemSize() const	{
 +        return SIZE;
 +    }
 +    int CurrentAllocs() const		{
 +        return _currentAllocs;
 +    }
 +
 +    virtual void* Alloc() {
 +        if ( !_root ) {
 +            // Need a new block.
 +            Block* block = new Block();
 +            _blockPtrs.Push( block );
 +
 +            for( int i=0; i<COUNT-1; ++i ) {
 +                block->chunk[i].next = &block->chunk[i+1];
 +            }
 +            block->chunk[COUNT-1].next = 0;
 +            _root = block->chunk;
 +        }
 +        void* result = _root;
 +        _root = _root->next;
 +
 +        ++_currentAllocs;
 +        if ( _currentAllocs > _maxAllocs ) {
 +            _maxAllocs = _currentAllocs;
 +        }
 +        _nAllocs++;
 +        _nUntracked++;
 +        return result;
 +    }
 +    
 +    virtual void Free( void* mem ) {
 +        if ( !mem ) {
 +            return;
 +        }
 +        --_currentAllocs;
 +        Chunk* chunk = static_cast<Chunk*>( mem );
 +#ifdef DEBUG
 +        memset( chunk, 0xfe, sizeof(Chunk) );
 +#endif
 +        chunk->next = _root;
 +        _root = chunk;
 +    }
 +    void Trace( const char* name ) {
 +        printf( "Mempool %s watermark=%d [%dk] current=%d size=%d nAlloc=%d blocks=%d\n",
 +                name, _maxAllocs, _maxAllocs*SIZE/1024, _currentAllocs, SIZE, _nAllocs, _blockPtrs.Size() );
 +    }
 +
 +    void SetTracked() {
 +        _nUntracked--;
 +    }
 +
 +    int Untracked() const {
 +        return _nUntracked;
 +    }
 +
 +	// This number is perf sensitive. 4k seems like a good tradeoff on my machine.
 +	// The test file is large, 170k.
 +	// Release:		VS2010 gcc(no opt)
 +	//		1k:		4000
 +	//		2k:		4000
 +	//		4k:		3900	21000
 +	//		16k:	5200
 +	//		32k:	4300
 +	//		64k:	4000	21000
 +    enum { COUNT = (4*1024)/SIZE }; // Some compilers do not accept to use COUNT in private part if COUNT is private
 +
 +private:
 +    MemPoolT( const MemPoolT& ); // not supported
 +    void operator=( const MemPoolT& ); // not supported
 +
 +    union Chunk {
 +        Chunk*  next;
 +        char    mem[SIZE];
 +    };
 +    struct Block {
 +        Chunk chunk[COUNT];
 +    };
 +    DynArray< Block*, 10 > _blockPtrs;
 +    Chunk* _root;
 +
 +    int _currentAllocs;
 +    int _nAllocs;
 +    int _maxAllocs;
 +    int _nUntracked;
 +};
 +
 +
 +
 +/**
 +	Implements the interface to the "Visitor pattern" (see the Accept() method.)
 +	If you call the Accept() method, it requires being passed a XMLVisitor
 +	class to handle callbacks. For nodes that contain other nodes (Document, Element)
 +	you will get called with a VisitEnter/VisitExit pair. Nodes that are always leafs
 +	are simply called with Visit().
 +
 +	If you return 'true' from a Visit method, recursive parsing will continue. If you return
 +	false, <b>no children of this node or its siblings</b> will be visited.
 +
 +	All flavors of Visit methods have a default implementation that returns 'true' (continue
 +	visiting). You need to only override methods that are interesting to you.
 +
 +	Generally Accept() is called on the XMLDocument, although all nodes support visiting.
 +
 +	You should never change the document from a callback.
 +
 +	@sa XMLNode::Accept()
 +*/
 +class TINYXML2_LIB XMLVisitor
 +{
 +public:
 +    virtual ~XMLVisitor() {}
 +
 +    /// Visit a document.
 +    virtual bool VisitEnter( const XMLDocument& /*doc*/ )			{
 +        return true;
 +    }
 +    /// Visit a document.
 +    virtual bool VisitExit( const XMLDocument& /*doc*/ )			{
 +        return true;
 +    }
 +
 +    /// Visit an element.
 +    virtual bool VisitEnter( const XMLElement& /*element*/, const XMLAttribute* /*firstAttribute*/ )	{
 +        return true;
 +    }
 +    /// Visit an element.
 +    virtual bool VisitExit( const XMLElement& /*element*/ )			{
 +        return true;
 +    }
 +
 +    /// Visit a declaration.
 +    virtual bool Visit( const XMLDeclaration& /*declaration*/ )		{
 +        return true;
 +    }
 +    /// Visit a text node.
 +    virtual bool Visit( const XMLText& /*text*/ )					{
 +        return true;
 +    }
 +    /// Visit a comment node.
 +    virtual bool Visit( const XMLComment& /*comment*/ )				{
 +        return true;
 +    }
 +    /// Visit an unknown node.
 +    virtual bool Visit( const XMLUnknown& /*unknown*/ )				{
 +        return true;
 +    }
 +};
 +
 +// WARNING: must match XMLDocument::_errorNames[]
 +enum XMLError {
 +    XML_SUCCESS = 0,
 +    XML_NO_ERROR = 0,
 +    XML_NO_ATTRIBUTE,
 +    XML_WRONG_ATTRIBUTE_TYPE,
 +    XML_ERROR_FILE_NOT_FOUND,
 +    XML_ERROR_FILE_COULD_NOT_BE_OPENED,
 +    XML_ERROR_FILE_READ_ERROR,
 +    XML_ERROR_ELEMENT_MISMATCH,
 +    XML_ERROR_PARSING_ELEMENT,
 +    XML_ERROR_PARSING_ATTRIBUTE,
 +    XML_ERROR_IDENTIFYING_TAG,
 +    XML_ERROR_PARSING_TEXT,
 +    XML_ERROR_PARSING_CDATA,
 +    XML_ERROR_PARSING_COMMENT,
 +    XML_ERROR_PARSING_DECLARATION,
 +    XML_ERROR_PARSING_UNKNOWN,
 +    XML_ERROR_EMPTY_DOCUMENT,
 +    XML_ERROR_MISMATCHED_ELEMENT,
 +    XML_ERROR_PARSING,
 +    XML_CAN_NOT_CONVERT_TEXT,
 +    XML_NO_TEXT_NODE,
 +
 +	XML_ERROR_COUNT
 +};
 +
 +
 +/*
 +	Utility functionality.
 +*/
 +class XMLUtil
 +{
 +public:
 +    static const char* SkipWhiteSpace( const char* p )	{
 +        TIXMLASSERT( p );
 +        while( IsWhiteSpace(*p) ) {
 +            ++p;
 +        }
 +        TIXMLASSERT( p );
 +        return p;
 +    }
 +    static char* SkipWhiteSpace( char* p )				{
 +        return const_cast<char*>( SkipWhiteSpace( const_cast<const char*>(p) ) );
 +    }
 +
 +    // Anything in the high order range of UTF-8 is assumed to not be whitespace. This isn't
 +    // correct, but simple, and usually works.
 +    static bool IsWhiteSpace( char p )					{
 +        return !IsUTF8Continuation(p) && isspace( static_cast<unsigned char>(p) );
 +    }
 +    
 +    inline static bool IsNameStartChar( unsigned char ch ) {
 +        if ( ch >= 128 ) {
 +            // This is a heuristic guess in attempt to not implement Unicode-aware isalpha()
 +            return true;
 +        }
 +        if ( isalpha( ch ) ) {
 +            return true;
 +        }
 +        return ch == ':' || ch == '_';
 +    }
 +    
 +    inline static bool IsNameChar( unsigned char ch ) {
 +        return IsNameStartChar( ch )
 +               || isdigit( ch )
 +               || ch == '.'
 +               || ch == '-';
 +    }
 +
 +    inline static bool StringEqual( const char* p, const char* q, int nChar=INT_MAX )  {
 +        if ( p == q ) {
 +            return true;
 +        }
 +        return strncmp( p, q, nChar ) == 0;
 +    }
 +    
 +    inline static bool IsUTF8Continuation( char p ) {
 +        return ( p & 0x80 ) != 0;
 +    }
 +
 +    static const char* ReadBOM( const char* p, bool* hasBOM );
 +    // p is the starting location,
 +    // the UTF-8 value of the entity will be placed in value, and length filled in.
 +    static const char* GetCharacterRef( const char* p, char* value, int* length );
 +    static void ConvertUTF32ToUTF8( unsigned long input, char* output, int* length );
 +
 +    // converts primitive types to strings
 +    static void ToStr( int v, char* buffer, int bufferSize );
 +    static void ToStr( unsigned v, char* buffer, int bufferSize );
 +    static void ToStr( bool v, char* buffer, int bufferSize );
 +    static void ToStr( float v, char* buffer, int bufferSize );
 +    static void ToStr( double v, char* buffer, int bufferSize );
 +
 +    // converts strings to primitive types
 +    static bool	ToInt( const char* str, int* value );
 +    static bool ToUnsigned( const char* str, unsigned* value );
 +    static bool	ToBool( const char* str, bool* value );
 +    static bool	ToFloat( const char* str, float* value );
 +    static bool ToDouble( const char* str, double* value );
 +};
 +
 +
 +/** XMLNode is a base class for every object that is in the
 +	XML Document Object Model (DOM), except XMLAttributes.
 +	Nodes have siblings, a parent, and children which can
 +	be navigated. A node is always in a XMLDocument.
 +	The type of a XMLNode can be queried, and it can
 +	be cast to its more defined type.
 +
 +	A XMLDocument allocates memory for all its Nodes.
 +	When the XMLDocument gets deleted, all its Nodes
 +	will also be deleted.
 +
 +	@verbatim
 +	A Document can contain:	Element	(container or leaf)
 +							Comment (leaf)
 +							Unknown (leaf)
 +							Declaration( leaf )
 +
 +	An Element can contain:	Element (container or leaf)
 +							Text	(leaf)
 +							Attributes (not on tree)
 +							Comment (leaf)
 +							Unknown (leaf)
 +
 +	@endverbatim
 +*/
 +class TINYXML2_LIB XMLNode
 +{
 +    friend class XMLDocument;
 +    friend class XMLElement;
 +public:
 +
 +    /// Get the XMLDocument that owns this XMLNode.
 +    const XMLDocument* GetDocument() const	{
 +        TIXMLASSERT( _document );
 +        return _document;
 +    }
 +    /// Get the XMLDocument that owns this XMLNode.
 +    XMLDocument* GetDocument()				{
 +        TIXMLASSERT( _document );
 +        return _document;
 +    }
 +
 +    /// Safely cast to an Element, or null.
 +    virtual XMLElement*		ToElement()		{
 +        return 0;
 +    }
 +    /// Safely cast to Text, or null.
 +    virtual XMLText*		ToText()		{
 +        return 0;
 +    }
 +    /// Safely cast to a Comment, or null.
 +    virtual XMLComment*		ToComment()		{
 +        return 0;
 +    }
 +    /// Safely cast to a Document, or null.
 +    virtual XMLDocument*	ToDocument()	{
 +        return 0;
 +    }
 +    /// Safely cast to a Declaration, or null.
 +    virtual XMLDeclaration*	ToDeclaration()	{
 +        return 0;
 +    }
 +    /// Safely cast to an Unknown, or null.
 +    virtual XMLUnknown*		ToUnknown()		{
 +        return 0;
 +    }
 +
 +    virtual const XMLElement*		ToElement() const		{
 +        return 0;
 +    }
 +    virtual const XMLText*			ToText() const			{
 +        return 0;
 +    }
 +    virtual const XMLComment*		ToComment() const		{
 +        return 0;
 +    }
 +    virtual const XMLDocument*		ToDocument() const		{
 +        return 0;
 +    }
 +    virtual const XMLDeclaration*	ToDeclaration() const	{
 +        return 0;
 +    }
 +    virtual const XMLUnknown*		ToUnknown() const		{
 +        return 0;
 +    }
 +
 +    /** The meaning of 'value' changes for the specific type.
 +    	@verbatim
 +    	Document:	empty (NULL is returned, not an empty string)
 +    	Element:	name of the element
 +    	Comment:	the comment text
 +    	Unknown:	the tag contents
 +    	Text:		the text string
 +    	@endverbatim
 +    */
 +    const char* Value() const;
 +
 +    /** Set the Value of an XML node.
 +    	@sa Value()
 +    */
 +    void SetValue( const char* val, bool staticMem=false );
 +
 +    /// Get the parent of this node on the DOM.
 +    const XMLNode*	Parent() const			{
 +        return _parent;
 +    }
 +
 +    XMLNode* Parent()						{
 +        return _parent;
 +    }
 +
 +    /// Returns true if this node has no children.
 +    bool NoChildren() const					{
 +        return !_firstChild;
 +    }
 +
 +    /// Get the first child node, or null if none exists.
 +    const XMLNode*  FirstChild() const		{
 +        return _firstChild;
 +    }
 +
 +    XMLNode*		FirstChild()			{
 +        return _firstChild;
 +    }
 +
 +    /** Get the first child element, or optionally the first child
 +        element with the specified name.
 +    */
 +    const XMLElement* FirstChildElement( const char* name = 0 ) const;
 +
 +    XMLElement* FirstChildElement( const char* name = 0 )	{
 +        return const_cast<XMLElement*>(const_cast<const XMLNode*>(this)->FirstChildElement( name ));
 +    }
 +
 +    /// Get the last child node, or null if none exists.
 +    const XMLNode*	LastChild() const						{
 +        return _lastChild;
 +    }
 +
 +    XMLNode*		LastChild()								{
 +        return _lastChild;
 +    }
 +
 +    /** Get the last child element or optionally the last child
 +        element with the specified name.
 +    */
 +    const XMLElement* LastChildElement( const char* name = 0 ) const;
 +
 +    XMLElement* LastChildElement( const char* name = 0 )	{
 +        return const_cast<XMLElement*>(const_cast<const XMLNode*>(this)->LastChildElement(name) );
 +    }
 +
 +    /// Get the previous (left) sibling node of this node.
 +    const XMLNode*	PreviousSibling() const					{
 +        return _prev;
 +    }
 +
 +    XMLNode*	PreviousSibling()							{
 +        return _prev;
 +    }
 +
 +    /// Get the previous (left) sibling element of this node, with an optionally supplied name.
 +    const XMLElement*	PreviousSiblingElement( const char* name = 0 ) const ;
 +
 +    XMLElement*	PreviousSiblingElement( const char* name = 0 ) {
 +        return const_cast<XMLElement*>(const_cast<const XMLNode*>(this)->PreviousSiblingElement( name ) );
 +    }
 +
 +    /// Get the next (right) sibling node of this node.
 +    const XMLNode*	NextSibling() const						{
 +        return _next;
 +    }
 +
 +    XMLNode*	NextSibling()								{
 +        return _next;
 +    }
 +
 +    /// Get the next (right) sibling element of this node, with an optionally supplied name.
 +    const XMLElement*	NextSiblingElement( const char* name = 0 ) const;
 +
 +    XMLElement*	NextSiblingElement( const char* name = 0 )	{
 +        return const_cast<XMLElement*>(const_cast<const XMLNode*>(this)->NextSiblingElement( name ) );
 +    }
 +
 +    /**
 +    	Add a child node as the last (right) child.
 +		If the child node is already part of the document,
 +		it is moved from its old location to the new location.
 +		Returns the addThis argument or 0 if the node does not
 +		belong to the same document.
 +    */
 +    XMLNode* InsertEndChild( XMLNode* addThis );
 +
 +    XMLNode* LinkEndChild( XMLNode* addThis )	{
 +        return InsertEndChild( addThis );
 +    }
 +    /**
 +    	Add a child node as the first (left) child.
 +		If the child node is already part of the document,
 +		it is moved from its old location to the new location.
 +		Returns the addThis argument or 0 if the node does not
 +		belong to the same document.
 +    */
 +    XMLNode* InsertFirstChild( XMLNode* addThis );
 +    /**
 +    	Add a node after the specified child node.
 +		If the child node is already part of the document,
 +		it is moved from its old location to the new location.
 +		Returns the addThis argument or 0 if the afterThis node
 +		is not a child of this node, or if the node does not
 +		belong to the same document.
 +    */
 +    XMLNode* InsertAfterChild( XMLNode* afterThis, XMLNode* addThis );
 +
 +    /**
 +    	Delete all the children of this node.
 +    */
 +    void DeleteChildren();
 +
 +    /**
 +    	Delete a child of this node.
 +    */
 +    void DeleteChild( XMLNode* node );
 +
 +    /**
 +    	Make a copy of this node, but not its children.
 +    	You may pass in a Document pointer that will be
 +    	the owner of the new Node. If the 'document' is
 +    	null, then the node returned will be allocated
 +    	from the current Document. (this->GetDocument())
 +
 +    	Note: if called on a XMLDocument, this will return null.
 +    */
 +    virtual XMLNode* ShallowClone( XMLDocument* document ) const = 0;
 +
 +    /**
 +    	Test if 2 nodes are the same, but don't test children.
 +    	The 2 nodes do not need to be in the same Document.
 +
 +    	Note: if called on a XMLDocument, this will return false.
 +    */
 +    virtual bool ShallowEqual( const XMLNode* compare ) const = 0;
 +
 +    /** Accept a hierarchical visit of the nodes in the TinyXML-2 DOM. Every node in the
 +    	XML tree will be conditionally visited and the host will be called back
 +    	via the XMLVisitor interface.
 +
 +    	This is essentially a SAX interface for TinyXML-2. (Note however it doesn't re-parse
 +    	the XML for the callbacks, so the performance of TinyXML-2 is unchanged by using this
 +    	interface versus any other.)
 +
 +    	The interface has been based on ideas from:
 +
 +    	- http://www.saxproject.org/
 +    	- http://c2.com/cgi/wiki?HierarchicalVisitorPattern
 +
 +    	Which are both good references for "visiting".
 +
 +    	An example of using Accept():
 +    	@verbatim
 +    	XMLPrinter printer;
 +    	tinyxmlDoc.Accept( &printer );
 +    	const char* xmlcstr = printer.CStr();
 +    	@endverbatim
 +    */
 +    virtual bool Accept( XMLVisitor* visitor ) const = 0;
 +
 +protected:
 +    XMLNode( XMLDocument* );
 +    virtual ~XMLNode();
 +
 +    virtual char* ParseDeep( char*, StrPair* );
 +
 +    XMLDocument*	_document;
 +    XMLNode*		_parent;
 +    mutable StrPair	_value;
 +
 +    XMLNode*		_firstChild;
 +    XMLNode*		_lastChild;
 +
 +    XMLNode*		_prev;
 +    XMLNode*		_next;
 +
 +private:
 +    MemPool*		_memPool;
 +    void Unlink( XMLNode* child );
 +    static void DeleteNode( XMLNode* node );
 +    void InsertChildPreamble( XMLNode* insertThis ) const;
 +
 +    XMLNode( const XMLNode& );	// not supported
 +    XMLNode& operator=( const XMLNode& );	// not supported
 +};
 +
 +
 +/** XML text.
 +
 +	Note that a text node can have child element nodes, for example:
 +	@verbatim
 +	<root>This is <b>bold</b></root>
 +	@endverbatim
 +
 +	A text node can have 2 ways to output the next. "normal" output
 +	and CDATA. It will default to the mode it was parsed from the XML file and
 +	you generally want to leave it alone, but you can change the output mode with
 +	SetCData() and query it with CData().
 +*/
 +class TINYXML2_LIB XMLText : public XMLNode
 +{
 +    friend class XMLBase;
 +    friend class XMLDocument;
 +public:
 +    virtual bool Accept( XMLVisitor* visitor ) const;
 +
 +    virtual XMLText* ToText()			{
 +        return this;
 +    }
 +    virtual const XMLText* ToText() const	{
 +        return this;
 +    }
 +
 +    /// Declare whether this should be CDATA or standard text.
 +    void SetCData( bool isCData )			{
 +        _isCData = isCData;
 +    }
 +    /// Returns true if this is a CDATA text element.
 +    bool CData() const						{
 +        return _isCData;
 +    }
 +
 +    virtual XMLNode* ShallowClone( XMLDocument* document ) const;
 +    virtual bool ShallowEqual( const XMLNode* compare ) const;
 +
 +protected:
 +    XMLText( XMLDocument* doc )	: XMLNode( doc ), _isCData( false )	{}
 +    virtual ~XMLText()												{}
 +
 +    char* ParseDeep( char*, StrPair* endTag );
 +
 +private:
 +    bool _isCData;
 +
 +    XMLText( const XMLText& );	// not supported
 +    XMLText& operator=( const XMLText& );	// not supported
 +};
 +
 +
 +/** An XML Comment. */
 +class TINYXML2_LIB XMLComment : public XMLNode
 +{
 +    friend class XMLDocument;
 +public:
 +    virtual XMLComment*	ToComment()					{
 +        return this;
 +    }
 +    virtual const XMLComment* ToComment() const		{
 +        return this;
 +    }
 +
 +    virtual bool Accept( XMLVisitor* visitor ) const;
 +
 +    virtual XMLNode* ShallowClone( XMLDocument* document ) const;
 +    virtual bool ShallowEqual( const XMLNode* compare ) const;
 +
 +protected:
 +    XMLComment( XMLDocument* doc );
 +    virtual ~XMLComment();
 +
 +    char* ParseDeep( char*, StrPair* endTag );
 +
 +private:
 +    XMLComment( const XMLComment& );	// not supported
 +    XMLComment& operator=( const XMLComment& );	// not supported
 +};
 +
 +
 +/** In correct XML the declaration is the first entry in the file.
 +	@verbatim
 +		<?xml version="1.0" standalone="yes"?>
 +	@endverbatim
 +
 +	TinyXML-2 will happily read or write files without a declaration,
 +	however.
 +
 +	The text of the declaration isn't interpreted. It is parsed
 +	and written as a string.
 +*/
 +class TINYXML2_LIB XMLDeclaration : public XMLNode
 +{
 +    friend class XMLDocument;
 +public:
 +    virtual XMLDeclaration*	ToDeclaration()					{
 +        return this;
 +    }
 +    virtual const XMLDeclaration* ToDeclaration() const		{
 +        return this;
 +    }
 +
 +    virtual bool Accept( XMLVisitor* visitor ) const;
 +
 +    virtual XMLNode* ShallowClone( XMLDocument* document ) const;
 +    virtual bool ShallowEqual( const XMLNode* compare ) const;
 +
 +protected:
 +    XMLDeclaration( XMLDocument* doc );
 +    virtual ~XMLDeclaration();
 +
 +    char* ParseDeep( char*, StrPair* endTag );
 +
 +private:
 +    XMLDeclaration( const XMLDeclaration& );	// not supported
 +    XMLDeclaration& operator=( const XMLDeclaration& );	// not supported
 +};
 +
 +
 +/** Any tag that TinyXML-2 doesn't recognize is saved as an
 +	unknown. It is a tag of text, but should not be modified.
 +	It will be written back to the XML, unchanged, when the file
 +	is saved.
 +
 +	DTD tags get thrown into XMLUnknowns.
 +*/
 +class TINYXML2_LIB XMLUnknown : public XMLNode
 +{
 +    friend class XMLDocument;
 +public:
 +    virtual XMLUnknown*	ToUnknown()					{
 +        return this;
 +    }
 +    virtual const XMLUnknown* ToUnknown() const		{
 +        return this;
 +    }
 +
 +    virtual bool Accept( XMLVisitor* visitor ) const;
 +
 +    virtual XMLNode* ShallowClone( XMLDocument* document ) const;
 +    virtual bool ShallowEqual( const XMLNode* compare ) const;
 +
 +protected:
 +    XMLUnknown( XMLDocument* doc );
 +    virtual ~XMLUnknown();
 +
 +    char* ParseDeep( char*, StrPair* endTag );
 +
 +private:
 +    XMLUnknown( const XMLUnknown& );	// not supported
 +    XMLUnknown& operator=( const XMLUnknown& );	// not supported
 +};
 +
 +
 +
 +/** An attribute is a name-value pair. Elements have an arbitrary
 +	number of attributes, each with a unique name.
 +
 +	@note The attributes are not XMLNodes. You may only query the
 +	Next() attribute in a list.
 +*/
 +class TINYXML2_LIB XMLAttribute
 +{
 +    friend class XMLElement;
 +public:
 +    /// The name of the attribute.
 +    const char* Name() const;
 +
 +    /// The value of the attribute.
 +    const char* Value() const;
 +
 +    /// The next attribute in the list.
 +    const XMLAttribute* Next() const {
 +        return _next;
 +    }
 +
 +    /** IntValue interprets the attribute as an integer, and returns the value.
 +        If the value isn't an integer, 0 will be returned. There is no error checking;
 +    	use QueryIntValue() if you need error checking.
 +    */
 +    int		 IntValue() const				{
 +        int i=0;
 +        QueryIntValue( &i );
 +        return i;
 +    }
 +    /// Query as an unsigned integer. See IntValue()
 +    unsigned UnsignedValue() const			{
 +        unsigned i=0;
 +        QueryUnsignedValue( &i );
 +        return i;
 +    }
 +    /// Query as a boolean. See IntValue()
 +    bool	 BoolValue() const				{
 +        bool b=false;
 +        QueryBoolValue( &b );
 +        return b;
 +    }
 +    /// Query as a double. See IntValue()
 +    double 	 DoubleValue() const			{
 +        double d=0;
 +        QueryDoubleValue( &d );
 +        return d;
 +    }
 +    /// Query as a float. See IntValue()
 +    float	 FloatValue() const				{
 +        float f=0;
 +        QueryFloatValue( &f );
 +        return f;
 +    }
 +
 +    /** QueryIntValue interprets the attribute as an integer, and returns the value
 +    	in the provided parameter. The function will return XML_NO_ERROR on success,
 +    	and XML_WRONG_ATTRIBUTE_TYPE if the conversion is not successful.
 +    */
 +    XMLError QueryIntValue( int* value ) const;
 +    /// See QueryIntValue
 +    XMLError QueryUnsignedValue( unsigned int* value ) const;
 +    /// See QueryIntValue
 +    XMLError QueryBoolValue( bool* value ) const;
 +    /// See QueryIntValue
 +    XMLError QueryDoubleValue( double* value ) const;
 +    /// See QueryIntValue
 +    XMLError QueryFloatValue( float* value ) const;
 +
 +    /// Set the attribute to a string value.
 +    void SetAttribute( const char* value );
 +    /// Set the attribute to value.
 +    void SetAttribute( int value );
 +    /// Set the attribute to value.
 +    void SetAttribute( unsigned value );
 +    /// Set the attribute to value.
 +    void SetAttribute( bool value );
 +    /// Set the attribute to value.
 +    void SetAttribute( double value );
 +    /// Set the attribute to value.
 +    void SetAttribute( float value );
 +
 +private:
 +    enum { BUF_SIZE = 200 };
 +
 +    XMLAttribute() : _next( 0 ), _memPool( 0 ) {}
 +    virtual ~XMLAttribute()	{}
 +
 +    XMLAttribute( const XMLAttribute& );	// not supported
 +    void operator=( const XMLAttribute& );	// not supported
 +    void SetName( const char* name );
 +
 +    char* ParseDeep( char* p, bool processEntities );
 +
 +    mutable StrPair _name;
 +    mutable StrPair _value;
 +    XMLAttribute*   _next;
 +    MemPool*        _memPool;
 +};
 +
 +
 +/** The element is a container class. It has a value, the element name,
 +	and can contain other elements, text, comments, and unknowns.
 +	Elements also contain an arbitrary number of attributes.
 +*/
 +class TINYXML2_LIB XMLElement : public XMLNode
 +{
 +    friend class XMLBase;
 +    friend class XMLDocument;
 +public:
 +    /// Get the name of an element (which is the Value() of the node.)
 +    const char* Name() const		{
 +        return Value();
 +    }
 +    /// Set the name of the element.
 +    void SetName( const char* str, bool staticMem=false )	{
 +        SetValue( str, staticMem );
 +    }
 +
 +    virtual XMLElement* ToElement()				{
 +        return this;
 +    }
 +    virtual const XMLElement* ToElement() const {
 +        return this;
 +    }
 +    virtual bool Accept( XMLVisitor* visitor ) const;
 +
 +    /** Given an attribute name, Attribute() returns the value
 +    	for the attribute of that name, or null if none
 +    	exists. For example:
 +
 +    	@verbatim
 +    	const char* value = ele->Attribute( "foo" );
 +    	@endverbatim
 +
 +    	The 'value' parameter is normally null. However, if specified,
 +    	the attribute will only be returned if the 'name' and 'value'
 +    	match. This allow you to write code:
 +
 +    	@verbatim
 +    	if ( ele->Attribute( "foo", "bar" ) ) callFooIsBar();
 +    	@endverbatim
 +
 +    	rather than:
 +    	@verbatim
 +    	if ( ele->Attribute( "foo" ) ) {
 +    		if ( strcmp( ele->Attribute( "foo" ), "bar" ) == 0 ) callFooIsBar();
 +    	}
 +    	@endverbatim
 +    */
 +    const char* Attribute( const char* name, const char* value=0 ) const;
 +
 +    /** Given an attribute name, IntAttribute() returns the value
 +    	of the attribute interpreted as an integer. 0 will be
 +    	returned if there is an error. For a method with error
 +    	checking, see QueryIntAttribute()
 +    */
 +    int		 IntAttribute( const char* name ) const		{
 +        int i=0;
 +        QueryIntAttribute( name, &i );
 +        return i;
 +    }
 +    /// See IntAttribute()
 +    unsigned UnsignedAttribute( const char* name ) const {
 +        unsigned i=0;
 +        QueryUnsignedAttribute( name, &i );
 +        return i;
 +    }
 +    /// See IntAttribute()
 +    bool	 BoolAttribute( const char* name ) const	{
 +        bool b=false;
 +        QueryBoolAttribute( name, &b );
 +        return b;
 +    }
 +    /// See IntAttribute()
 +    double 	 DoubleAttribute( const char* name ) const	{
 +        double d=0;
 +        QueryDoubleAttribute( name, &d );
 +        return d;
 +    }
 +    /// See IntAttribute()
 +    float	 FloatAttribute( const char* name ) const	{
 +        float f=0;
 +        QueryFloatAttribute( name, &f );
 +        return f;
 +    }
 +
 +    /** Given an attribute name, QueryIntAttribute() returns
 +    	XML_NO_ERROR, XML_WRONG_ATTRIBUTE_TYPE if the conversion
 +    	can't be performed, or XML_NO_ATTRIBUTE if the attribute
 +    	doesn't exist. If successful, the result of the conversion
 +    	will be written to 'value'. If not successful, nothing will
 +    	be written to 'value'. This allows you to provide default
 +    	value:
 +
 +    	@verbatim
 +    	int value = 10;
 +    	QueryIntAttribute( "foo", &value );		// if "foo" isn't found, value will still be 10
 +    	@endverbatim
 +    */
 +    XMLError QueryIntAttribute( const char* name, int* value ) const				{
 +        const XMLAttribute* a = FindAttribute( name );
 +        if ( !a ) {
 +            return XML_NO_ATTRIBUTE;
 +        }
 +        return a->QueryIntValue( value );
 +    }
 +    /// See QueryIntAttribute()
 +    XMLError QueryUnsignedAttribute( const char* name, unsigned int* value ) const	{
 +        const XMLAttribute* a = FindAttribute( name );
 +        if ( !a ) {
 +            return XML_NO_ATTRIBUTE;
 +        }
 +        return a->QueryUnsignedValue( value );
 +    }
 +    /// See QueryIntAttribute()
 +    XMLError QueryBoolAttribute( const char* name, bool* value ) const				{
 +        const XMLAttribute* a = FindAttribute( name );
 +        if ( !a ) {
 +            return XML_NO_ATTRIBUTE;
 +        }
 +        return a->QueryBoolValue( value );
 +    }
 +    /// See QueryIntAttribute()
 +    XMLError QueryDoubleAttribute( const char* name, double* value ) const			{
 +        const XMLAttribute* a = FindAttribute( name );
 +        if ( !a ) {
 +            return XML_NO_ATTRIBUTE;
 +        }
 +        return a->QueryDoubleValue( value );
 +    }
 +    /// See QueryIntAttribute()
 +    XMLError QueryFloatAttribute( const char* name, float* value ) const			{
 +        const XMLAttribute* a = FindAttribute( name );
 +        if ( !a ) {
 +            return XML_NO_ATTRIBUTE;
 +        }
 +        return a->QueryFloatValue( value );
 +    }
 +
 +	
 +    /** Given an attribute name, QueryAttribute() returns
 +    	XML_NO_ERROR, XML_WRONG_ATTRIBUTE_TYPE if the conversion
 +    	can't be performed, or XML_NO_ATTRIBUTE if the attribute
 +    	doesn't exist. It is overloaded for the primitive types,
 +		and is a generally more convenient replacement of
 +		QueryIntAttribute() and related functions.
 +		
 +		If successful, the result of the conversion
 +    	will be written to 'value'. If not successful, nothing will
 +    	be written to 'value'. This allows you to provide default
 +    	value:
 +
 +    	@verbatim
 +    	int value = 10;
 +    	QueryAttribute( "foo", &value );		// if "foo" isn't found, value will still be 10
 +    	@endverbatim
 +    */
 +	int QueryAttribute( const char* name, int* value ) const {
 +		return QueryIntAttribute( name, value );
 +	}
 +
 +	int QueryAttribute( const char* name, unsigned int* value ) const {
 +		return QueryUnsignedAttribute( name, value );
 +	}
 +
 +	int QueryAttribute( const char* name, bool* value ) const {
 +		return QueryBoolAttribute( name, value );
 +	}
 +
 +	int QueryAttribute( const char* name, double* value ) const {
 +		return QueryDoubleAttribute( name, value );
 +	}
 +
 +	int QueryAttribute( const char* name, float* value ) const {
 +		return QueryFloatAttribute( name, value );
 +	}
 +
 +	/// Sets the named attribute to value.
 +    void SetAttribute( const char* name, const char* value )	{
 +        XMLAttribute* a = FindOrCreateAttribute( name );
 +        a->SetAttribute( value );
 +    }
 +    /// Sets the named attribute to value.
 +    void SetAttribute( const char* name, int value )			{
 +        XMLAttribute* a = FindOrCreateAttribute( name );
 +        a->SetAttribute( value );
 +    }
 +    /// Sets the named attribute to value.
 +    void SetAttribute( const char* name, unsigned value )		{
 +        XMLAttribute* a = FindOrCreateAttribute( name );
 +        a->SetAttribute( value );
 +    }
 +    /// Sets the named attribute to value.
 +    void SetAttribute( const char* name, bool value )			{
 +        XMLAttribute* a = FindOrCreateAttribute( name );
 +        a->SetAttribute( value );
 +    }
 +    /// Sets the named attribute to value.
 +    void SetAttribute( const char* name, double value )		{
 +        XMLAttribute* a = FindOrCreateAttribute( name );
 +        a->SetAttribute( value );
 +    }
 +    /// Sets the named attribute to value.
 +    void SetAttribute( const char* name, float value )		{
 +        XMLAttribute* a = FindOrCreateAttribute( name );
 +        a->SetAttribute( value );
 +    }
 +
 +    /**
 +    	Delete an attribute.
 +    */
 +    void DeleteAttribute( const char* name );
 +
 +    /// Return the first attribute in the list.
 +    const XMLAttribute* FirstAttribute() const {
 +        return _rootAttribute;
 +    }
 +    /// Query a specific attribute in the list.
 +    const XMLAttribute* FindAttribute( const char* name ) const;
 +
 +    /** Convenience function for easy access to the text inside an element. Although easy
 +    	and concise, GetText() is limited compared to getting the XMLText child
 +    	and accessing it directly.
 +
 +    	If the first child of 'this' is a XMLText, the GetText()
 +    	returns the character string of the Text node, else null is returned.
 +
 +    	This is a convenient method for getting the text of simple contained text:
 +    	@verbatim
 +    	<foo>This is text</foo>
 +    		const char* str = fooElement->GetText();
 +    	@endverbatim
 +
 +    	'str' will be a pointer to "This is text".
 +
 +    	Note that this function can be misleading. If the element foo was created from
 +    	this XML:
 +    	@verbatim
 +    		<foo><b>This is text</b></foo>
 +    	@endverbatim
 +
 +    	then the value of str would be null. The first child node isn't a text node, it is
 +    	another element. From this XML:
 +    	@verbatim
 +    		<foo>This is <b>text</b></foo>
 +    	@endverbatim
 +    	GetText() will return "This is ".
 +    */
 +    const char* GetText() const;
 +
 +    /** Convenience function for easy access to the text inside an element. Although easy
 +    	and concise, SetText() is limited compared to creating an XMLText child
 +    	and mutating it directly.
 +
 +    	If the first child of 'this' is a XMLText, SetText() sets its value to
 +		the given string, otherwise it will create a first child that is an XMLText.
 +
 +    	This is a convenient method for setting the text of simple contained text:
 +    	@verbatim
 +    	<foo>This is text</foo>
 +    		fooElement->SetText( "Hullaballoo!" );
 +     	<foo>Hullaballoo!</foo>
 +		@endverbatim
 +
 +    	Note that this function can be misleading. If the element foo was created from
 +    	this XML:
 +    	@verbatim
 +    		<foo><b>This is text</b></foo>
 +    	@endverbatim
 +
 +    	then it will not change "This is text", but rather prefix it with a text element:
 +    	@verbatim
 +    		<foo>Hullaballoo!<b>This is text</b></foo>
 +    	@endverbatim
 +		
 +		For this XML:
 +    	@verbatim
 +    		<foo />
 +    	@endverbatim
 +    	SetText() will generate
 +    	@verbatim
 +    		<foo>Hullaballoo!</foo>
 +    	@endverbatim
 +    */
 +	void SetText( const char* inText );
 +    /// Convenience method for setting text inside an element. See SetText() for important limitations.
 +    void SetText( int value );
 +    /// Convenience method for setting text inside an element. See SetText() for important limitations.
 +    void SetText( unsigned value );  
 +    /// Convenience method for setting text inside an element. See SetText() for important limitations.
 +    void SetText( bool value );  
 +    /// Convenience method for setting text inside an element. See SetText() for important limitations.
 +    void SetText( double value );  
 +    /// Convenience method for setting text inside an element. See SetText() for important limitations.
 +    void SetText( float value );  
 +
 +    /**
 +    	Convenience method to query the value of a child text node. This is probably best
 +    	shown by example. Given you have a document is this form:
 +    	@verbatim
 +    		<point>
 +    			<x>1</x>
 +    			<y>1.4</y>
 +    		</point>
 +    	@endverbatim
 +
 +    	The QueryIntText() and similar functions provide a safe and easier way to get to the
 +    	"value" of x and y.
 +
 +    	@verbatim
 +    		int x = 0;
 +    		float y = 0;	// types of x and y are contrived for example
 +    		const XMLElement* xElement = pointElement->FirstChildElement( "x" );
 +    		const XMLElement* yElement = pointElement->FirstChildElement( "y" );
 +    		xElement->QueryIntText( &x );
 +    		yElement->QueryFloatText( &y );
 +    	@endverbatim
 +
 +    	@returns XML_SUCCESS (0) on success, XML_CAN_NOT_CONVERT_TEXT if the text cannot be converted
 +    			 to the requested type, and XML_NO_TEXT_NODE if there is no child text to query.
 +
 +    */
 +    XMLError QueryIntText( int* ival ) const;
 +    /// See QueryIntText()
 +    XMLError QueryUnsignedText( unsigned* uval ) const;
 +    /// See QueryIntText()
 +    XMLError QueryBoolText( bool* bval ) const;
 +    /// See QueryIntText()
 +    XMLError QueryDoubleText( double* dval ) const;
 +    /// See QueryIntText()
 +    XMLError QueryFloatText( float* fval ) const;
 +
 +    // internal:
 +    enum {
 +        OPEN,		// <foo>
 +        CLOSED,		// <foo/>
 +        CLOSING		// </foo>
 +    };
 +    int ClosingType() const {
 +        return _closingType;
 +    }
 +    virtual XMLNode* ShallowClone( XMLDocument* document ) const;
 +    virtual bool ShallowEqual( const XMLNode* compare ) const;
 +
 +protected:
 +    char* ParseDeep( char* p, StrPair* endTag );
 +
 +private:
 +    XMLElement( XMLDocument* doc );
 +    virtual ~XMLElement();
 +    XMLElement( const XMLElement& );	// not supported
 +    void operator=( const XMLElement& );	// not supported
 +
 +    XMLAttribute* FindAttribute( const char* name ) {
 +        return const_cast<XMLAttribute*>(const_cast<const XMLElement*>(this)->FindAttribute( name ));
 +    }
 +    XMLAttribute* FindOrCreateAttribute( const char* name );
 +    //void LinkAttribute( XMLAttribute* attrib );
 +    char* ParseAttributes( char* p );
 +    static void DeleteAttribute( XMLAttribute* attribute );
 +
 +    enum { BUF_SIZE = 200 };
 +    int _closingType;
 +    // The attribute list is ordered; there is no 'lastAttribute'
 +    // because the list needs to be scanned for dupes before adding
 +    // a new attribute.
 +    XMLAttribute* _rootAttribute;
 +};
 +
 +
 +enum Whitespace {
 +    PRESERVE_WHITESPACE,
 +    COLLAPSE_WHITESPACE
 +};
 +
 +
 +/** A Document binds together all the functionality.
 +	It can be saved, loaded, and printed to the screen.
 +	All Nodes are connected and allocated to a Document.
 +	If the Document is deleted, all its Nodes are also deleted.
 +*/
 +class TINYXML2_LIB XMLDocument : public XMLNode
 +{
 +    friend class XMLElement;
 +public:
 +    /// constructor
 +    XMLDocument( bool processEntities = true, Whitespace = PRESERVE_WHITESPACE );
 +    ~XMLDocument();
 +
 +    virtual XMLDocument* ToDocument()				{
 +        TIXMLASSERT( this == _document );
 +        return this;
 +    }
 +    virtual const XMLDocument* ToDocument() const	{
 +        TIXMLASSERT( this == _document );
 +        return this;
 +    }
 +
 +    /**
 +    	Parse an XML file from a character string.
 +    	Returns XML_NO_ERROR (0) on success, or
 +    	an errorID.
 +
 +    	You may optionally pass in the 'nBytes', which is
 +    	the number of bytes which will be parsed. If not
 +    	specified, TinyXML-2 will assume 'xml' points to a
 +    	null terminated string.
 +    */
 +    XMLError Parse( const char* xml, size_t nBytes=(size_t)(-1) );
 +
 +    /**
 +    	Load an XML file from disk.
 +    	Returns XML_NO_ERROR (0) on success, or
 +    	an errorID.
 +    */
 +    XMLError LoadFile( const char* filename );
 +
 +    /**
 +    	Load an XML file from disk. You are responsible
 +    	for providing and closing the FILE*. 
 +     
 +        NOTE: The file should be opened as binary ("rb")
 +        not text in order for TinyXML-2 to correctly
 +        do newline normalization.
 +
 +    	Returns XML_NO_ERROR (0) on success, or
 +    	an errorID.
 +    */
 +    XMLError LoadFile( FILE* );
 +
 +    /**
 +    	Save the XML file to disk.
 +    	Returns XML_NO_ERROR (0) on success, or
 +    	an errorID.
 +    */
 +    XMLError SaveFile( const char* filename, bool compact = false );
 +
 +    /**
 +    	Save the XML file to disk. You are responsible
 +    	for providing and closing the FILE*.
 +
 +    	Returns XML_NO_ERROR (0) on success, or
 +    	an errorID.
 +    */
 +    XMLError SaveFile( FILE* fp, bool compact = false );
 +
 +    bool ProcessEntities() const		{
 +        return _processEntities;
 +    }
 +    Whitespace WhitespaceMode() const	{
 +        return _whitespace;
 +    }
 +
 +    /**
 +    	Returns true if this document has a leading Byte Order Mark of UTF8.
 +    */
 +    bool HasBOM() const {
 +        return _writeBOM;
 +    }
 +    /** Sets whether to write the BOM when writing the file.
 +    */
 +    void SetBOM( bool useBOM ) {
 +        _writeBOM = useBOM;
 +    }
 +
 +    /** Return the root element of DOM. Equivalent to FirstChildElement().
 +        To get the first node, use FirstChild().
 +    */
 +    XMLElement* RootElement()				{
 +        return FirstChildElement();
 +    }
 +    const XMLElement* RootElement() const	{
 +        return FirstChildElement();
 +    }
 +
 +    /** Print the Document. If the Printer is not provided, it will
 +        print to stdout. If you provide Printer, this can print to a file:
 +    	@verbatim
 +    	XMLPrinter printer( fp );
 +    	doc.Print( &printer );
 +    	@endverbatim
 +
 +    	Or you can use a printer to print to memory:
 +    	@verbatim
 +    	XMLPrinter printer;
 +    	doc.Print( &printer );
 +    	// printer.CStr() has a const char* to the XML
 +    	@endverbatim
 +    */
 +    void Print( XMLPrinter* streamer=0 ) const;
 +    virtual bool Accept( XMLVisitor* visitor ) const;
 +
 +    /**
 +    	Create a new Element associated with
 +    	this Document. The memory for the Element
 +    	is managed by the Document.
 +    */
 +    XMLElement* NewElement( const char* name );
 +    /**
 +    	Create a new Comment associated with
 +    	this Document. The memory for the Comment
 +    	is managed by the Document.
 +    */
 +    XMLComment* NewComment( const char* comment );
 +    /**
 +    	Create a new Text associated with
 +    	this Document. The memory for the Text
 +    	is managed by the Document.
 +    */
 +    XMLText* NewText( const char* text );
 +    /**
 +    	Create a new Declaration associated with
 +    	this Document. The memory for the object
 +    	is managed by the Document.
 +
 +    	If the 'text' param is null, the standard
 +    	declaration is used.:
 +    	@verbatim
 +    		<?xml version="1.0" encoding="UTF-8"?>
 +    	@endverbatim
 +    */
 +    XMLDeclaration* NewDeclaration( const char* text=0 );
 +    /**
 +    	Create a new Unknown associated with
 +    	this Document. The memory for the object
 +    	is managed by the Document.
 +    */
 +    XMLUnknown* NewUnknown( const char* text );
 +
 +    /**
 +    	Delete a node associated with this document.
 +    	It will be unlinked from the DOM.
 +    */
 +    void DeleteNode( XMLNode* node );
 +
 +    void SetError( XMLError error, const char* str1, const char* str2 );
 +
 +    /// Return true if there was an error parsing the document.
 +    bool Error() const {
 +        return _errorID != XML_NO_ERROR;
 +    }
 +    /// Return the errorID.
 +    XMLError  ErrorID() const {
 +        return _errorID;
 +    }
 +	const char* ErrorName() const;
 +
 +    /// Return a possibly helpful diagnostic location or string.
 +    const char* GetErrorStr1() const {
 +        return _errorStr1;
 +    }
 +    /// Return a possibly helpful secondary diagnostic location or string.
 +    const char* GetErrorStr2() const {
 +        return _errorStr2;
 +    }
 +    /// If there is an error, print it to stdout.
 +    void PrintError() const;
 +    
 +    /// Clear the document, resetting it to the initial state.
 +    void Clear();
 +
 +    // internal
 +    char* Identify( char* p, XMLNode** node );
 +
 +    virtual XMLNode* ShallowClone( XMLDocument* /*document*/ ) const	{
 +        return 0;
 +    }
 +    virtual bool ShallowEqual( const XMLNode* /*compare*/ ) const	{
 +        return false;
 +    }
 +
 +private:
 +    XMLDocument( const XMLDocument& );	// not supported
 +    void operator=( const XMLDocument& );	// not supported
 +
 +    bool        _writeBOM;
 +    bool        _processEntities;
 +    XMLError    _errorID;
 +    Whitespace  _whitespace;
 +    const char* _errorStr1;
 +    const char* _errorStr2;
 +    char*       _charBuffer;
 +
 +    MemPoolT< sizeof(XMLElement) >	 _elementPool;
 +    MemPoolT< sizeof(XMLAttribute) > _attributePool;
 +    MemPoolT< sizeof(XMLText) >		 _textPool;
 +    MemPoolT< sizeof(XMLComment) >	 _commentPool;
 +
 +	static const char* _errorNames[XML_ERROR_COUNT];
 +
 +    void Parse();
 +};
 +
 +
 +/**
 +	A XMLHandle is a class that wraps a node pointer with null checks; this is
 +	an incredibly useful thing. Note that XMLHandle is not part of the TinyXML-2
 +	DOM structure. It is a separate utility class.
 +
 +	Take an example:
 +	@verbatim
 +	<Document>
 +		<Element attributeA = "valueA">
 +			<Child attributeB = "value1" />
 +			<Child attributeB = "value2" />
 +		</Element>
 +	</Document>
 +	@endverbatim
 +
 +	Assuming you want the value of "attributeB" in the 2nd "Child" element, it's very
 +	easy to write a *lot* of code that looks like:
 +
 +	@verbatim
 +	XMLElement* root = document.FirstChildElement( "Document" );
 +	if ( root )
 +	{
 +		XMLElement* element = root->FirstChildElement( "Element" );
 +		if ( element )
 +		{
 +			XMLElement* child = element->FirstChildElement( "Child" );
 +			if ( child )
 +			{
 +				XMLElement* child2 = child->NextSiblingElement( "Child" );
 +				if ( child2 )
 +				{
 +					// Finally do something useful.
 +	@endverbatim
 +
 +	And that doesn't even cover "else" cases. XMLHandle addresses the verbosity
 +	of such code. A XMLHandle checks for null pointers so it is perfectly safe
 +	and correct to use:
 +
 +	@verbatim
 +	XMLHandle docHandle( &document );
 +	XMLElement* child2 = docHandle.FirstChildElement( "Document" ).FirstChildElement( "Element" ).FirstChildElement().NextSiblingElement();
 +	if ( child2 )
 +	{
 +		// do something useful
 +	@endverbatim
 +
 +	Which is MUCH more concise and useful.
 +
 +	It is also safe to copy handles - internally they are nothing more than node pointers.
 +	@verbatim
 +	XMLHandle handleCopy = handle;
 +	@endverbatim
 +
 +	See also XMLConstHandle, which is the same as XMLHandle, but operates on const objects.
 +*/
 +class TINYXML2_LIB XMLHandle
 +{
 +public:
 +    /// Create a handle from any node (at any depth of the tree.) This can be a null pointer.
 +    XMLHandle( XMLNode* node )												{
 +        _node = node;
 +    }
 +    /// Create a handle from a node.
 +    XMLHandle( XMLNode& node )												{
 +        _node = &node;
 +    }
 +    /// Copy constructor
 +    XMLHandle( const XMLHandle& ref )										{
 +        _node = ref._node;
 +    }
 +    /// Assignment
 +    XMLHandle& operator=( const XMLHandle& ref )							{
 +        _node = ref._node;
 +        return *this;
 +    }
 +
 +    /// Get the first child of this handle.
 +    XMLHandle FirstChild() 													{
 +        return XMLHandle( _node ? _node->FirstChild() : 0 );
 +    }
 +    /// Get the first child element of this handle.
 +    XMLHandle FirstChildElement( const char* name = 0 )						{
 +        return XMLHandle( _node ? _node->FirstChildElement( name ) : 0 );
 +    }
 +    /// Get the last child of this handle.
 +    XMLHandle LastChild()													{
 +        return XMLHandle( _node ? _node->LastChild() : 0 );
 +    }
 +    /// Get the last child element of this handle.
 +    XMLHandle LastChildElement( const char* name = 0 )						{
 +        return XMLHandle( _node ? _node->LastChildElement( name ) : 0 );
 +    }
 +    /// Get the previous sibling of this handle.
 +    XMLHandle PreviousSibling()												{
 +        return XMLHandle( _node ? _node->PreviousSibling() : 0 );
 +    }
 +    /// Get the previous sibling element of this handle.
 +    XMLHandle PreviousSiblingElement( const char* name = 0 )				{
 +        return XMLHandle( _node ? _node->PreviousSiblingElement( name ) : 0 );
 +    }
 +    /// Get the next sibling of this handle.
 +    XMLHandle NextSibling()													{
 +        return XMLHandle( _node ? _node->NextSibling() : 0 );
 +    }
 +    /// Get the next sibling element of this handle.
 +    XMLHandle NextSiblingElement( const char* name = 0 )					{
 +        return XMLHandle( _node ? _node->NextSiblingElement( name ) : 0 );
 +    }
 +
 +    /// Safe cast to XMLNode. This can return null.
 +    XMLNode* ToNode()							{
 +        return _node;
 +    }
 +    /// Safe cast to XMLElement. This can return null.
 +    XMLElement* ToElement() 					{
 +        return ( ( _node == 0 ) ? 0 : _node->ToElement() );
 +    }
 +    /// Safe cast to XMLText. This can return null.
 +    XMLText* ToText() 							{
 +        return ( ( _node == 0 ) ? 0 : _node->ToText() );
 +    }
 +    /// Safe cast to XMLUnknown. This can return null.
 +    XMLUnknown* ToUnknown() 					{
 +        return ( ( _node == 0 ) ? 0 : _node->ToUnknown() );
 +    }
 +    /// Safe cast to XMLDeclaration. This can return null.
 +    XMLDeclaration* ToDeclaration() 			{
 +        return ( ( _node == 0 ) ? 0 : _node->ToDeclaration() );
 +    }
 +
 +private:
 +    XMLNode* _node;
 +};
 +
 +
 +/**
 +	A variant of the XMLHandle class for working with const XMLNodes and Documents. It is the
 +	same in all regards, except for the 'const' qualifiers. See XMLHandle for API.
 +*/
 +class TINYXML2_LIB XMLConstHandle
 +{
 +public:
 +    XMLConstHandle( const XMLNode* node )											{
 +        _node = node;
 +    }
 +    XMLConstHandle( const XMLNode& node )											{
 +        _node = &node;
 +    }
 +    XMLConstHandle( const XMLConstHandle& ref )										{
 +        _node = ref._node;
 +    }
 +
 +    XMLConstHandle& operator=( const XMLConstHandle& ref )							{
 +        _node = ref._node;
 +        return *this;
 +    }
 +
 +    const XMLConstHandle FirstChild() const											{
 +        return XMLConstHandle( _node ? _node->FirstChild() : 0 );
 +    }
 +    const XMLConstHandle FirstChildElement( const char* name = 0 ) const				{
 +        return XMLConstHandle( _node ? _node->FirstChildElement( name ) : 0 );
 +    }
 +    const XMLConstHandle LastChild()	const										{
 +        return XMLConstHandle( _node ? _node->LastChild() : 0 );
 +    }
 +    const XMLConstHandle LastChildElement( const char* name = 0 ) const				{
 +        return XMLConstHandle( _node ? _node->LastChildElement( name ) : 0 );
 +    }
 +    const XMLConstHandle PreviousSibling() const									{
 +        return XMLConstHandle( _node ? _node->PreviousSibling() : 0 );
 +    }
 +    const XMLConstHandle PreviousSiblingElement( const char* name = 0 ) const		{
 +        return XMLConstHandle( _node ? _node->PreviousSiblingElement( name ) : 0 );
 +    }
 +    const XMLConstHandle NextSibling() const										{
 +        return XMLConstHandle( _node ? _node->NextSibling() : 0 );
 +    }
 +    const XMLConstHandle NextSiblingElement( const char* name = 0 ) const			{
 +        return XMLConstHandle( _node ? _node->NextSiblingElement( name ) : 0 );
 +    }
 +
 +
 +    const XMLNode* ToNode() const				{
 +        return _node;
 +    }
 +    const XMLElement* ToElement() const			{
 +        return ( ( _node == 0 ) ? 0 : _node->ToElement() );
 +    }
 +    const XMLText* ToText() const				{
 +        return ( ( _node == 0 ) ? 0 : _node->ToText() );
 +    }
 +    const XMLUnknown* ToUnknown() const			{
 +        return ( ( _node == 0 ) ? 0 : _node->ToUnknown() );
 +    }
 +    const XMLDeclaration* ToDeclaration() const	{
 +        return ( ( _node == 0 ) ? 0 : _node->ToDeclaration() );
 +    }
 +
 +private:
 +    const XMLNode* _node;
 +};
 +
 +
 +/**
 +	Printing functionality. The XMLPrinter gives you more
 +	options than the XMLDocument::Print() method.
 +
 +	It can:
 +	-# Print to memory.
 +	-# Print to a file you provide.
 +	-# Print XML without a XMLDocument.
 +
 +	Print to Memory
 +
 +	@verbatim
 +	XMLPrinter printer;
 +	doc.Print( &printer );
 +	SomeFunction( printer.CStr() );
 +	@endverbatim
 +
 +	Print to a File
 +
 +	You provide the file pointer.
 +	@verbatim
 +	XMLPrinter printer( fp );
 +	doc.Print( &printer );
 +	@endverbatim
 +
 +	Print without a XMLDocument
 +
 +	When loading, an XML parser is very useful. However, sometimes
 +	when saving, it just gets in the way. The code is often set up
 +	for streaming, and constructing the DOM is just overhead.
 +
 +	The Printer supports the streaming case. The following code
 +	prints out a trivially simple XML file without ever creating
 +	an XML document.
 +
 +	@verbatim
 +	XMLPrinter printer( fp );
 +	printer.OpenElement( "foo" );
 +	printer.PushAttribute( "foo", "bar" );
 +	printer.CloseElement();
 +	@endverbatim
 +*/
 +class TINYXML2_LIB XMLPrinter : public XMLVisitor
 +{
 +public:
 +    /** Construct the printer. If the FILE* is specified,
 +    	this will print to the FILE. Else it will print
 +    	to memory, and the result is available in CStr().
 +    	If 'compact' is set to true, then output is created
 +    	with only required whitespace and newlines.
 +    */
 +    XMLPrinter( FILE* file=0, bool compact = false, int depth = 0 );
 +    virtual ~XMLPrinter()	{}
 +
 +    /** If streaming, write the BOM and declaration. */
 +    void PushHeader( bool writeBOM, bool writeDeclaration );
 +    /** If streaming, start writing an element.
 +        The element must be closed with CloseElement()
 +    */
 +    void OpenElement( const char* name, bool compactMode=false );
 +    /// If streaming, add an attribute to an open element.
 +    void PushAttribute( const char* name, const char* value );
 +    void PushAttribute( const char* name, int value );
 +    void PushAttribute( const char* name, unsigned value );
 +    void PushAttribute( const char* name, bool value );
 +    void PushAttribute( const char* name, double value );
 +    /// If streaming, close the Element.
 +    virtual void CloseElement( bool compactMode=false );
 +
 +    /// Add a text node.
 +    void PushText( const char* text, bool cdata=false );
 +    /// Add a text node from an integer.
 +    void PushText( int value );
 +    /// Add a text node from an unsigned.
 +    void PushText( unsigned value );
 +    /// Add a text node from a bool.
 +    void PushText( bool value );
 +    /// Add a text node from a float.
 +    void PushText( float value );
 +    /// Add a text node from a double.
 +    void PushText( double value );
 +
 +    /// Add a comment
 +    void PushComment( const char* comment );
 +
 +    void PushDeclaration( const char* value );
 +    void PushUnknown( const char* value );
 +
 +    virtual bool VisitEnter( const XMLDocument& /*doc*/ );
 +    virtual bool VisitExit( const XMLDocument& /*doc*/ )			{
 +        return true;
 +    }
 +
 +    virtual bool VisitEnter( const XMLElement& element, const XMLAttribute* attribute );
 +    virtual bool VisitExit( const XMLElement& element );
 +
 +    virtual bool Visit( const XMLText& text );
 +    virtual bool Visit( const XMLComment& comment );
 +    virtual bool Visit( const XMLDeclaration& declaration );
 +    virtual bool Visit( const XMLUnknown& unknown );
 +
 +    /**
 +    	If in print to memory mode, return a pointer to
 +    	the XML file in memory.
 +    */
 +    const char* CStr() const {
 +        return _buffer.Mem();
 +    }
 +    /**
 +    	If in print to memory mode, return the size
 +    	of the XML file in memory. (Note the size returned
 +    	includes the terminating null.)
 +    */
 +    int CStrSize() const {
 +        return _buffer.Size();
 +    }
 +    /**
 +    	If in print to memory mode, reset the buffer to the
 +    	beginning.
 +    */
 +    void ClearBuffer() {
 +        _buffer.Clear();
 +        _buffer.Push(0);
 +    }
 +
 +protected:
 +	virtual bool CompactMode( const XMLElement& )	{ return _compactMode; }
 +
 +	/** Prints out the space before an element. You may override to change
 +	    the space and tabs used. A PrintSpace() override should call Print().
 +	*/
 +    virtual void PrintSpace( int depth );
 +    void Print( const char* format, ... );
 +
 +    void SealElementIfJustOpened();
 +    bool _elementJustOpened;
 +    DynArray< const char*, 10 > _stack;
 +
 +private:
 +    void PrintString( const char*, bool restrictedEntitySet );	// prints out, after detecting entities.
 +
 +    bool _firstElement;
 +    FILE* _fp;
 +    int _depth;
 +    int _textDepth;
 +    bool _processEntities;
 +	bool _compactMode;
 +
 +    enum {
 +        ENTITY_RANGE = 64,
 +        BUF_SIZE = 200
 +    };
 +    bool _entityFlag[ENTITY_RANGE];
 +    bool _restrictedEntityFlag[ENTITY_RANGE];
 +
 +    DynArray< char, 20 > _buffer;
 +};
 +
 +
 +}	// tinyxml2
 +
 +#if defined(_MSC_VER)
 +#   pragma warning(pop)
 +#endif
 +
 +#endif // TINYXML2_INCLUDED
 diff --git a/hw3/include/transformation3d.h b/hw3/include/transformation3d.h new file mode 100644 index 0000000..7b61ecc --- /dev/null +++ b/hw3/include/transformation3d.h @@ -0,0 +1,77 @@ +/******************************************************************/ +/* This file is part of the homework assignments for CSCI-427/527 */ +/* at The College of William & Mary and authored by Pieter Peers. */ +/* No part of this file, whether altered or in original form, can */ +/* be distributed or used outside the context of CSCI-427/527     */ +/* without consent of either the College of William & Mary or     */ +/* Pieter Peers.                                                  */ +/******************************************************************/ +#ifndef _TRANSFORMATION3D_H_ +#define _TRANSFORMATION3D_H_ + +#include "vec3d.h" +#include "mat3d.h" + +class transformation3d { + public: +  ////////////////// +  // Constructors // +  ////////////////// +  transformation3d(void); +  transformation3d(const vec3d& translation, const mat3d& transformation, const mat3d& inverseTransform); +  transformation3d(const transformation3d& t); + +  ////////////// +  // Operator // +  ////////////// +  transformation3d& operator=(const transformation3d& t); + +  transformation3d operator*(const transformation3d& t) const; +  transformation3d& operator*=(const transformation3d& t); + +  ////////////// +  // Mutators // +  ////////////// +  transformation3d& invert(void); + +  ///////////// +  // Methods // +  ///////////// +  vec3d transformPoint(const vec3d& p) const; +  vec3d transformDirection(const vec3d& d) const; +  vec3d transformNormal(const vec3d& n) const; + +  vec3d inverseTransformPoint(const vec3d& p) const; +  vec3d inverseTransformDirection(const vec3d& d) const; +  vec3d inverseTransformNormal(const vec3d& n) const; + +  ///////////// +  // Friends // +  ///////////// +  friend void swap(transformation3d& a, transformation3d& b) { a._swap(b); } + +  friend transformation3d inverse(const transformation3d& t) { transformation3d i(t); return i.invert(); } + +  friend std::ostream& operator<<(std::ostream& s, const transformation3d& t) +  { +    t._print(s); +    return s; +  } + + protected: +  /////////////////////// +  // Protected Methods // +  /////////////////////// +  void _swap(transformation3d& t); +  void _assign(const transformation3d& t); +  virtual void _print(std::ostream& s) const; + +  //////////////////////////// +  // Protected Data Members // +  //////////////////////////// +  vec3d _translation; +  mat3d _transformation; +  mat3d _inverseTransformation; +}; + +#endif /* _TRANSFORMATION3D_H_ */ diff --git a/hw3/include/triangle.h b/hw3/include/triangle.h new file mode 100644 index 0000000..f7d85bf --- /dev/null +++ b/hw3/include/triangle.h @@ -0,0 +1,115 @@ +/******************************************************************/ +/* This file is part of the homework assignments for CSCI-427/527 */ +/* at The College of William & Mary and authored by Pieter Peers. */ +/* No part of this file, whether altered or in original form, can */ +/* be distributed or used outside the context of CSCI-427/527     */ +/* without consent of either the College of William & Mary or     */ +/* Pieter Peers.                                                  */ +/******************************************************************/ +#ifndef _TRIANGLE_H_ +#define _TRIANGLE_H_ + +#include <array> +#include <vector> +#include <memory> +#include <ostream> + +#include "ray.h" +#include "vec2d.h" +#include "vec3d.h" +#include "boundingBox.h" + +class triangle { + public: +  ////////////////// +  // Constructors // +  ////////////////// +  triangle(void); +  triangle(const triangle& t); +  triangle(triangle&& t); + +  triangle(const vec3d& v1, const vec3d& v2, const vec3d& v3); +  triangle(size_t v1_idx, size_t v2_idx, size_t v3_idx, const std::shared_ptr<const std::vector<vec3d>>& vertex_list); + +  triangle(const vec3d& v1, const vec3d& v2, const vec3d& v3, +	   const vec3d& n1, const vec3d& n2, const vec3d& n3); +  triangle(size_t v1_idx, size_t v2_idx, size_t v3_idx, const std::shared_ptr<const std::vector<vec3d>>& vertex_list, +           size_t n1_idx, size_t n2_idx, size_t n3_idx, const std::shared_ptr<const std::vector<vec3d>>& normal_list); + +  triangle(const vec3d& v1, const vec3d& v2, const vec3d& v3, +	   const vec2d& t1, const vec2d& t2, const vec2d& t3); +  triangle(size_t v1_idx, size_t v2_idx, size_t v3_idx, const std::shared_ptr<const std::vector<vec3d>>& vertex_list, +	   size_t t1_idx, size_t t2_idx, size_t t3_idx, const std::shared_ptr<const std::vector<vec2d>>& texcoord_list); + +  triangle(const vec3d& v1, const vec3d& v2, const vec3d& v3, +	   const vec3d& n1, const vec3d& n2, const vec3d& n3, +	   const vec2d& t1, const vec2d& t2, const vec2d& t3); +  triangle(size_t v1_idx, size_t v2_idx, size_t v3_idx, const std::shared_ptr<const std::vector<vec3d>>& vertex_list, +	   size_t n1_idx, size_t n2_idx, size_t n3_idx, const std::shared_ptr<const std::vector<vec3d>>& normal_list, +	   size_t t1_idx, size_t t2_idx, size_t t3_idx, const std::shared_ptr<const std::vector<vec2d>>& texcoord_list); + +  //////////////// +  // Inspectors // +  //////////////// +  const vec3d& vertex(size_t index) const; +  const vec3d& normal(size_t index) const; +  const vec2d& textureCoordinate(size_t index) const; + +  bool hasPerVertexNormals(void) const; +  bool hasPerVertexTextureCoordinates(void) const; + +  /////////////// +  // Operators // +  /////////////// +  triangle& operator=(const triangle& t);   +  triangle& operator=(triangle&& t);  + +  ///////////// +  // Methods // +  ///////////// +  bool intersect(const ray& r, vec3d& barycentricCoord, float& t) const; + +  boundingBox boundingbox(void) const; +  vec3d vertex(const vec3d& barycentricCoord) const; +  vec3d normal(void) const; +  vec3d shadingAxis(void) const; +  vec3d normal(const vec3d& barycentricCoord) const; +  vec2d textureCoordinate(const vec3d& barycentricCoord) const; + +  vec3d sample(float r1, float r2, vec3d& barycentricCoord, float& pdf) const; +  float area(void) const; + +  ///////////// +  // Friends // +  ///////////// +  friend void swap(triangle& a, triangle& b) { a._swap(b); } +   +  friend std::ostream& operator<<(std::ostream& s, const triangle& t) +  { +    s << "Triangle: v=(" << t.vertex(0)            << "," << t.vertex(1)            << "," << t.vertex(2)            << ")"; +    if(t._normal_list)  +      s           << ", n=(" << t.normal(0)            << "," << t.normal(1)            << "," << t.normal(2)            << ")"; +    if(t._textureCoord_list)  +      s           << ", t=(" << t.textureCoordinate(0) << "," << t.textureCoordinate(1) << "," << t.textureCoordinate(2) << ")"; +    return s; +  } + +private: +  ///////////////////// +  // Private Methods // +  ///////////////////// +  void _assign(const triangle& t); +  void _swap(triangle& t);  + +  ////////////////// +  // Data Members // +  ////////////////// +  std::array<size_t, 3> _vertex_idx; +  std::array<size_t, 3> _normal_idx; +  std::array<size_t,3 > _textureCoord_idx; +  std::shared_ptr<const std::vector<vec3d>> _vertex_list; +  std::shared_ptr<const std::vector<vec3d>> _normal_list; +  std::shared_ptr<const std::vector<vec2d>> _textureCoord_list; +}; + +#endif /* _TRIANGLE_H_ */ diff --git a/hw3/include/triangleMesh.h b/hw3/include/triangleMesh.h new file mode 100644 index 0000000..9558602 --- /dev/null +++ b/hw3/include/triangleMesh.h @@ -0,0 +1,51 @@ +/******************************************************************/ +/* This file is part of the homework assignments for CSCI-427/527 */ +/* at The College of William & Mary and authored by Pieter Peers. */ +/* No part of this file, whether altered or in original form, can */ +/* be distributed or used outside the context of CSCI-427/527     */ +/* without consent of either the College of William & Mary or     */ +/* Pieter Peers.                                                  */ +/******************************************************************/ +#ifndef _TRIANGLEMESH_H_  +#define _TRIANGLEMESH_H_  + +#include "vec2d.h" +#include "vec3d.h" +#include "shader_base.h" +#include "boundedTriangle.h" +#include "boundedCompound.h" + +class triangleMesh : public boundedCompound { + public: +  ////////////////// +  // Constructors // +  ////////////////// +  triangleMesh(void); +  triangleMesh(const std::vector<triangle>& triangle_list, const std::shared_ptr<const shader_base>& shader, const transformation3d& transform=transformation3d()); +  triangleMesh(const triangleMesh&) = delete; + +  /////////////// +  // Operators // +  /////////////// +  triangleMesh& operator=(const triangleMesh&) = delete; + +  ///////////// +  // Methods // +  ///////////// +  virtual const std::vector<std::shared_ptr<const boundedPrimitive>>& compounds(void) const final override; + +  virtual bool hasShader(void) const override; + + private: +  ///////////////////// +  // Private Methods // +  ///////////////////// +  virtual void _print(std::ostream& s) const override; + +  ////////////////// +  // Data Members // +  ////////////////// +  std::vector<std::shared_ptr<const boundedPrimitive>> _triangles; +}; + +#endif /* _TRIANGLEMESH_H_ */ diff --git a/hw3/include/util.h b/hw3/include/util.h new file mode 100644 index 0000000..2146464 --- /dev/null +++ b/hw3/include/util.h @@ -0,0 +1,19 @@ +/******************************************************************/ +/* This file is part of the homework assignments for CSCI-427/527 */ +/* at The College of William & Mary and authored by Pieter Peers. */ +/* No part of this file, whether altered or in original form, can */ +/* be distributed or used outside the context of CSCI-427/527     */ +/* without consent of either the College of William & Mary or     */ +/* Pieter Peers.                                                  */ +/******************************************************************/ + +#ifndef _UTIL_H_ +#define _UTIL_H_ + +#include <string> + +std::string getFilename(const std::string& path); +std::string getExtension(const std::string& path); +std::string getDirectory(const std::string& path); + +#endif /* _UTIL_H_ */  diff --git a/hw3/include/vec2d.h b/hw3/include/vec2d.h new file mode 100644 index 0000000..36e0e5c --- /dev/null +++ b/hw3/include/vec2d.h @@ -0,0 +1,117 @@ +/******************************************************************/ +/* This file is part of the homework assignments for CSCI-427/527 */ +/* at The College of William & Mary and authored by Pieter Peers. */ +/* No part of this file, whether altered or in original form, can */ +/* be distributed or used outside the context of CSCI-427/527     */ +/* without consent of either the College of William & Mary or     */ +/* Pieter Peers.                                                  */ +/******************************************************************/ +#ifndef _VEC2D_H_ +#define _VEC2D_H_ + +#include <ostream> +#include <cmath> + +class vec2d { + public: +  ///////////// +  // Typedef // +  ///////////// +  typedef float             value_type; +  typedef value_type&       reference; +  typedef const value_type& const_reference; +  typedef value_type*       iterator; +  typedef const value_type* const_iterator; + +  ////////////////// +  // Data Members // +  ////////////////// +  union { +    struct { value_type x, y; }; +    struct { value_type u, v; }; +    value_type data[2]; +  }; + + public: +  ///////////////// +  // Constructor // +  ///////////////// +  explicit vec2d(const_reference value=0.0f); +  vec2d(const_reference x, const_reference y); +  vec2d(const vec2d& v); +  +  //////////////// +  // Inspectors // +  //////////////// +  static size_t size(void) { return 2; } + +  iterator begin(void); +  const_iterator begin(void) const; +  iterator end(void); +  const_iterator end(void) const; + +  const_reference  operator[](size_t index) const; +  reference        operator[](size_t index); + +  /////////////// +  // Operators // +  /////////////// +  vec2d& operator=(const vec2d& v); + +  bool operator==(const vec2d& v) const; +  bool operator!=(const vec2d& v) const; + +  vec2d operator-(void) const; +   +  vec2d operator+(const vec2d& v) const; +  vec2d operator-(const vec2d& v) const; +  vec2d operator*(const vec2d& v) const; +  vec2d operator*(const_reference scale) const; +  vec2d operator/(const vec2d& v) const; +  vec2d operator/(const_reference scale) const; + +  vec2d& operator+=(const vec2d& v); +  vec2d& operator-=(const vec2d& v); +  vec2d& operator*=(const vec2d& v); +  vec2d& operator*=(const_reference scale); +  vec2d& operator/=(const vec2d& v); +  vec2d& operator/=(const_reference scale); + +  ///////////// +  // Methods // +  ///////////// +  value_type dot(const vec2d& v) const; +  value_type squared_length(void) const; +  value_type length(void) const; +  value_type squared_distance(const vec2d& v) const; +  value_type distance(const vec2d& v) const; + +  /////////////// +  // Modifiers // +  /////////////// +  vec2d& abs(void); +  vec2d& normalize(void); + +  ///////////// +  // Friends // +  ///////////// +  friend void  swap(vec2d& a, vec2d& b) { return a._swap(b); } +  friend vec2d  normalize(const vec2d& v) { return vec2d(v).normalize(); } +  friend vec2d  abs(const vec2d& v) { return vec2d(v).abs(); }   +  friend vec2d operator*(const_reference scale, const vec2d& v) { return (v*scale); } + +  friend std::ostream& operator<<(std::ostream& s, const vec2d& v) +  { +    s << "[" << v.x << "," << v.y << "]"; +    return s; +  } + + private: +  ///////////////////// +  // Private Methods // +  ///////////////////// +  void _assign(const vec2d& v); +  void _swap(vec2d& v); +}; + +#endif /* _VEC2D_H_ */ diff --git a/hw3/include/vec3d.h b/hw3/include/vec3d.h new file mode 100644 index 0000000..50d918f --- /dev/null +++ b/hw3/include/vec3d.h @@ -0,0 +1,120 @@ +/******************************************************************/ +/* This file is part of the homework assignments for CSCI-427/527 */ +/* at The College of William & Mary and authored by Pieter Peers. */ +/* No part of this file, whether altered or in original form, can */ +/* be distributed or used outside the context of CSCI-427/527     */ +/* without consent of either the College of William & Mary or     */ +/* Pieter Peers.                                                  */ +/******************************************************************/ +#ifndef _VEC3D_H_ +#define _VEC3D_H_ + +#include <ostream> +#include <cmath> + +class vec3d { + public: +  ///////////// +  // Typedef // +  ///////////// +  typedef float             value_type; +  typedef value_type&       reference; +  typedef const value_type& const_reference; +  typedef value_type*       iterator; +  typedef const value_type* const_iterator; + +  ////////////////// +  // Data Members // +  ////////////////// +  union { +    struct { value_type x, y, z; }; +    value_type data[3]; +  }; + + public: +  ///////////////// +  // Constructor // +  ///////////////// +  explicit vec3d(const_reference value=0.0f); +  vec3d(const_reference x, const_reference y, const_reference z); +  vec3d(const vec3d& v); +  +  //////////////// +  // Inspectors // +  //////////////// +  static size_t size(void) { return 3; } + +  iterator begin(void); +  const_iterator begin(void) const; +  iterator end(void); +  const_iterator end(void) const; + +  const_reference  operator[](size_t index) const; +  reference        operator[](size_t index); + +  /////////////// +  // Operators // +  /////////////// +  vec3d& operator=(const vec3d& v); + +  bool operator==(const vec3d& v) const; +  bool operator!=(const vec3d& v) const; + +  vec3d operator-(void) const; +   +  vec3d operator+(const vec3d& v) const; +  vec3d operator-(const vec3d& v) const; +  vec3d operator*(const vec3d& v) const; +  vec3d operator*(const_reference scale) const; +  vec3d operator/(const vec3d& v) const; +  vec3d operator/(const_reference scale) const; + +  vec3d& operator+=(const vec3d& v); +  vec3d& operator-=(const vec3d& v); +  vec3d& operator*=(const vec3d& v); +  vec3d& operator*=(const_reference scale); +  vec3d& operator/=(const vec3d& v); +  vec3d& operator/=(const_reference scale); + +  ///////////// +  // Methods // +  ///////////// +  value_type dot(const vec3d& v) const; +  value_type squared_length(void) const; +  value_type length(void) const; +  value_type squared_distance(const vec3d& v) const; +  value_type distance(const vec3d& v) const; + +  vec3d cross(const vec3d& v) const; + +  /////////////// +  // Modifiers // +  /////////////// +  vec3d& abs(void); +  vec3d& clamp(value_type lower=0.0f, value_type upper=1.0f);  +  vec3d& normalize(void); + +  ///////////// +  // Friends // +  ///////////// +  friend void  swap(vec3d& a, vec3d& b) { return a._swap(b); } +  friend vec3d  normalize(const vec3d& v) { return vec3d(v).normalize(); } +  friend vec3d  abs(const vec3d& v) { return vec3d(v).abs(); }   +  friend vec3d  clamp(const vec3d& v, value_type lower=0.0f, value_type upper=1.0f) { return vec3d(v).clamp(lower, upper); } +  friend vec3d operator*(const_reference scale, const vec3d& v) { return (v*scale); } + +  friend std::ostream& operator<<(std::ostream& s, const vec3d& v) +  { +    s << "[" << v.x << "," << v.y << "," << v.z << "]"; +    return s; +  } + + private: +  ///////////////////// +  // Private Methods // +  ///////////////////// +  void _assign(const vec3d& v); +  void _swap(vec3d& v); +}; + +#endif /* _VEC3D_H_ */ |