diff --git a/shape.lua b/shape.lua
index ef54309137c191e6bc12ef948b7c65d956884b6c..98d795443e193632ca1a8624f17ec9e071dec8c4 100644
--- a/shape.lua
+++ b/shape.lua
@@ -3,6 +3,7 @@ require("kara3d.matrix")
 require("kara3d.quaternion")
 require("kara3d.transform")
 require("utils")
+re = require("re")
 
 shape = {class = "shape"}
 shape.__index = shape
@@ -85,3 +86,48 @@ function shape.cube(t, size)
 
   return shape.new(t, {left, right, bottom, top, back, front})
 end
+
+
+--[[
+  Load shape from mesh file. Only .off files supported for now, though
+]]--
+function shape.load(t, file)
+  local vertices = {}
+  local faces = {}
+  local vertexNumber = nil
+  local faceNumber = nil
+  local vertexRead = 0
+  local facesRead = 0
+  local linenumber = 0
+
+  for line in io.lines(file) do
+    linenumber = linenumber + 1
+    local blankMatch = re.match(line, "OFF|#.*")
+    if blankMatch == nil then
+      local matches = re.split(line, "[[:blank:]]+", true)
+      if matches ~= nil then
+        if vertexNumber == nil or faceNumber == nil then
+            vertexNumber = tonumber(matches[1])
+            faceNumber = tonumber(matches[2])
+        else
+          if vertexRead < vertexNumber then
+              vertices[#vertices+1] = {tonumber(matches[1]), tonumber(matches[2]), tonumber(matches[3])}
+              vertexRead = vertexRead + 1
+          else
+            local faceSize = tonumber(matches[1])
+            local faceVertices = {}
+            for i = 1, faceSize do
+                faceVertices[i] = vertices[tonumber(matches[i+1]) + 1]
+            end
+            local normal = vector.cross(vector.new(3, faceVertices[2]) - vector.new(3, faceVertices[1]),
+                                        vector.new(3, faceVertices[3]) - vector.new(3, faceVertices[1]))
+            faces[#faces+1] = face.new(faceVertices, normal)
+            facesRead = facesRead + 1
+          end
+        end
+      end
+    end
+  end
+
+  return shape.new(t, faces)
+end