diff --git a/doc/images/shape_cube_basic.jpg b/doc/images/shape_cube_basic.jpg
new file mode 100644
index 00000000..d5f26251
Binary files /dev/null and b/doc/images/shape_cube_basic.jpg differ
diff --git a/doc/images/shape_cube_parameterization.jpg b/doc/images/shape_cube_parameterization.jpg
new file mode 100644
index 00000000..d9f34781
Binary files /dev/null and b/doc/images/shape_cube_parameterization.jpg differ
diff --git a/src/shapes/CMakeLists.txt b/src/shapes/CMakeLists.txt
index e59f2b84..6c73ab39 100644
--- a/src/shapes/CMakeLists.txt
+++ b/src/shapes/CMakeLists.txt
@@ -15,6 +15,7 @@ add_shape(rectangle rectangle.cpp)
add_shape(disk disk.cpp)
add_shape(sphere sphere.cpp)
add_shape(cylinder cylinder.cpp)
+add_shape(cube cube.cpp)
add_shape(hair hair.h hair.cpp)
add_shape(shapegroup shapegroup.h shapegroup.cpp)
add_shape(instance instance.h instance.cpp)
diff --git a/src/shapes/SConscript b/src/shapes/SConscript
index 0d8a266d..db9f0728 100644
--- a/src/shapes/SConscript
+++ b/src/shapes/SConscript
@@ -11,6 +11,7 @@ plugins += env.SharedLibrary('cylinder', ['cylinder.cpp'])
plugins += env.SharedLibrary('hair', ['hair.cpp'])
plugins += env.SharedLibrary('shapegroup', ['shapegroup.cpp'])
plugins += env.SharedLibrary('instance', ['instance.cpp'])
+plugins += env.SharedLibrary('cube', ['cube.cpp'])
#plugins += env.SharedLibrary('deformable', ['deformable.cpp'])
Export('plugins')
diff --git a/src/shapes/cube.cpp b/src/shapes/cube.cpp
new file mode 100644
index 00000000..19b9841a
--- /dev/null
+++ b/src/shapes/cube.cpp
@@ -0,0 +1,115 @@
+/*
+ This file is part of Mitsuba, a physically based rendering system.
+
+ Copyright (c) 2007-2012 by Wenzel Jakob and others.
+
+ Mitsuba is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License Version 3
+ as published by the Free Software Foundation.
+
+ Mitsuba is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see .
+*/
+
+#include
+#include
+
+MTS_NAMESPACE_BEGIN
+
+static Float CubeData_vertexPositions[][3] = {{1, 0, 0}, {1, 0, 1}, {0, 0, 1}, {0, 0, 0}, {1, 1, 0}, {0, 1, 0}, {0, 1, 1}, {1, 1, 1}, {1, 0, 0}, {1, 1, 0}, {1, 1, 1}, {1, 0, 1}, {1, 0, 1}, {1, 1, 1}, {0, 1, 1}, {0, 0, 1}, {0, 0, 1}, {0, 1, 1}, {0, 1, 0}, {0, 0, 0}, {1, 1, 0}, {1, 0, 0}, {0, 0, 0}, {0, 1, 0}};
+
+static Float CubeData_vertexNormals[][3] = {{0, -1, 0}, {0, -1, 0}, {0, -1, 0}, {0, -1, 0}, {0, 1, 0}, {0, 1, 0}, {0, 1, 0}, {0, 1, 0}, {1, 0, 0}, {1, 0, 0}, {1, 0, 0}, {1, 0, 0}, {0, 0, 1}, {0, 0, 1}, {0, 0, 1}, {0, 0, 1}, {-1, 0, 0}, {-1, 0, 0}, {-1, 0, 0}, {-1, 0, 0}, {0, 0, -1}, {0, 0, -1}, {0, 0, -1}, {0, 0, -1}};
+
+static Float CubeData_texcoords[][2] = {{0, 1}, {1, 1}, {1, 0}, {0, 0}, {0, 1}, {1, 1}, {1, 0}, {0, 0}, {0, 1}, {1, 1}, {1, 0}, {0, 0}, {0, 1}, {1, 1}, {1, 0}, {0, 0}, {0, 1}, {1, 1}, {1, 0}, {0, 0}, {0, 1}, {1, 1}, {1, 0}, {0, 0}};
+
+static uint32_t CubeData_triangles[][3] = {{0, 1, 2}, {3, 0, 2}, {4, 5, 6}, {7, 4, 6}, {8, 9, 10}, {11, 8, 10}, {12, 13, 14}, {15, 12, 14}, {16, 17, 18}, {19, 16, 18}, {20, 21, 22}, {23, 20, 22}};
+
+/*!\plugin{cube}{Cube intersection primitive}
+ * \order{0}
+ * \parameters{
+ * \parameter{toWorld}{\Transform\Or\Animation}{
+ * Specifies an optional linear object-to-world transformation.
+ * \default{none (i.e. object space $=$ world space)}
+ * }
+ * \parameter{flipNormals}{\Boolean}{
+ * Is the cube inverted, i.e. should the normal vectors
+ * be flipped? \default{\code{false}, i.e. the normals point outside}
+ * }
+ * }
+ *
+ * \renderings{
+ * \rendering{Basic example, see \lstref{cube-basic}}
+ * {shape_cube_basic}
+ * \rendering{A textured and stretched cube with the default parameterization
+ * (Listing~\ref{lst:cube-example})}
+ * {shape_cube_parameterization}
+ * }
+ *
+ * This shape plugin describes a simple cube/cuboid intersection primitive. By
+ * default, it creates a cube between the world-space positions $(0, 0, 0)$ and $(1,1,1)$.
+ * However, an arbitrary linear transformation may be specified to translate, rotate, scale
+ * or skew it as desired. The parameterization of this shape maps every face onto the
+ * rectangle $[0,1]^2$ in $uv$ space.
+ * \vspace{5mm}
+ * \begin{xml}[caption={Example of a textured and stretched cube}, label=lst:cube-example]
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ * \end{xml}
+ */
+class Cube : public TriMesh {
+public:
+ Cube(const Properties &props) : TriMesh(props) {
+ m_name = props.getID();
+ m_triangleCount = 12;
+ m_vertexCount = 24;
+ m_positions = new Point[m_vertexCount];
+ m_texcoords = new Point2[m_vertexCount];
+ m_normals = new Normal[m_vertexCount];
+ m_triangles = new Triangle[m_triangleCount];
+
+ Transform toWorld = props.getTransform("toWorld", Transform());
+ for (uint32_t i=0; i