diff --git a/src/components/tools/drawing-manager.js b/src/components/tools/drawing-manager.js
index 9b4da53e14a929db1636177c96b0d00b94a378ab..34d8f64887094c35fb2ffdcb214278f842181520 100644
--- a/src/components/tools/drawing-manager.js
+++ b/src/components/tools/drawing-manager.js
@@ -3,11 +3,52 @@
  * @component drawing-manager
  */
 AFRAME.registerComponent("drawing-manager", {
-  schema: {},
+  schema: {
+    drawing: { type: "string" }
+  },
 
-  init() {},
+  init() {
+    this.handleDrawingInitialized = this.handleDrawingInitialized.bind(this);
 
-  play() {},
+    // this.drawingEl = document.querySelector(this.data.drawing);
+    this.drawingToPen = new Map();
 
-  pause() {}
+    // if (this.drawingEl.hasLoaded) {
+    //   this.drawing = this.drawingEl.components["networked-drawing"];
+    // } else {
+    //   this.drawingEl.addEventListener("componentinitialized", this.handleDrawingInitialized);
+    // }
+  },
+
+  remove() {
+    // this.drawingEl.removeEventListener("componentinitialized", this.handleDrawingInitialized);
+  },
+
+  play() {
+    this.drawing = document.querySelector(this.data.drawing).components["networked-drawing"];
+  },
+
+  pause() {},
+
+  handleDrawingInitialized(e) {
+    if (e.detail.name === "networked-drawing") {
+      this.drawing = this.drawingEl.components["networked-drawing"];
+    }
+  },
+
+  getDrawing(pen) {
+    //TODO: future handling of multiple drawings
+    if (this.drawing && (!this.drawingToPen.has(this.drawing) || this.drawingToPen.get(this.drawing) === pen)) {
+      this.drawingToPen.set(this.drawing, pen);
+      return this.drawing;
+    }
+
+    return null;
+  },
+
+  returnDrawing(pen) {
+    if (this.drawingToPen.has(this.drawing) && this.drawingToPen.get(this.drawing) === pen) {
+      this.drawingToPen.delete(this.drawing);
+    }
+  }
 });
diff --git a/src/components/tools/networked-drawing.js b/src/components/tools/networked-drawing.js
index efb7a424e2634665362a228ac39c290b4a6d65ed..d1b9e564f6575f5fd2787644a4d212dc03344e1b 100644
--- a/src/components/tools/networked-drawing.js
+++ b/src/components/tools/networked-drawing.js
@@ -6,6 +6,9 @@
 
 import SharedBufferGeometryManager from "../../vendor/sharedbuffergeometrymanager";
 
+const MSG_CONFIRM_CONNECT = 0;
+const MSG_BUFFER_DATA = 1;
+
 function round(x) {
   return Math.round(x * 100000) / 100000;
 }
@@ -20,28 +23,26 @@ function copyData(fromArray, toArray, fromIndex, toIndex) {
 
 AFRAME.registerComponent("networked-drawing", {
   schema: {
-    segments: { default: 8 },
-    radius: { default: 0.02 },
-    color: { type: "color", default: "#FF0000" }
+    segments: { default: 3 },
+    radius: { default: 0.2 },
+    color: { type: "color", default: "#FF0000" },
+    drawTimeout: { default: 5000 }
   },
 
   init() {
     this.drawBuffer = [];
+    this.bufferIndex = 0;
+    this.drawBufferHistory = [];
 
     const options = {
-      //seems to require calling computeVertexNormals() if > 0
-      roughness: 0,
-      metalness: 0,
-      vertexColors: THREE.VertexColors,
-      side: THREE.DoubleSide
+      vertexColors: THREE.VertexColors
     };
 
     this.color = new THREE.Color(this.data.color);
     this.radius = this.data.radius;
     this.segments = this.data.segments;
 
-    const material = new THREE.MeshBasicMaterial(options);
-    console.log(material);
+    const material = new THREE.MeshStandardMaterial(options);
     this.sharedBufferGeometryManager = new SharedBufferGeometryManager();
     this.sharedBufferGeometryManager.addSharedBuffer(0, material, THREE.TriangleStripDrawMode);
 
@@ -53,7 +54,7 @@ AFRAME.registerComponent("networked-drawing", {
     }
 
     this.sharedBuffer = this.sharedBufferGeometryManager.getSharedBuffer(0);
-    this.drawing = this.sharedBuffer.getDrawing();
+    this.drawing = this.sharedBuffer.drawing;
     const sceneEl = document.querySelector("a-scene");
     this.scene = sceneEl.object3D;
     this.scene.add(this.drawing);
@@ -62,31 +63,32 @@ AFRAME.registerComponent("networked-drawing", {
     this.remoteLineStarted = false;
 
     this.lastPoint = new THREE.Vector3();
-    this.initialized = false;
+    this.lastDrawTime = -1;
 
-    this.bufferIndex = 0;
+    this.connectedToOwner = false;
 
-    this.sendDrawBuffer = this.sendDrawBuffer.bind(this);
-    this.receiveDrawBuffer = this.receiveDrawBuffer.bind(this);
+    this.prevIdx = Object.assign({}, this.sharedBuffer.idx);
+    this.idx = Object.assign({}, this.sharedBuffer.idx);
+    this.vertexCount = 0;
 
-    document.body.addEventListener("clientConnected", this.sendDrawBuffer);
+    this.receiveData = this.receiveData.bind(this);
 
     NAF.connection.onConnect(() => {
       NAF.utils.getNetworkedEntity(this.el).then(networkedEl => {
         this.networkedEl = networkedEl;
-
-        this.drawingId = "drawing-" + NAF.utils.getNetworkId(this.networkedEl);
-
-        if (!NAF.utils.isMine(this.networkedEl)) {
-          NAF.connection.subscribeToDataChannel(this.drawingId, this.receiveDrawBuffer);
+        this.networkId = NAF.utils.getNetworkId(this.networkedEl);
+        if (!this.networkId) {
+          console.error("No networkId for", this.networkedEl);
         }
+        this.drawingId = "drawing-" + this.networkId;
+
+        NAF.connection.subscribeToDataChannel(this.drawingId, this.receiveData);
       });
     });
   },
 
   remove() {
-    document.body.removeEventListener("clientConnected", this.sendDrawBuffer);
-    NAF.connection.unsubscribeToDataChannel(this.drawingId, this.receiveDrawBuffer);
+    NAF.connection.unsubscribeToDataChannel(this.drawingId, this.receiveData);
 
     this.scene.remove(this.drawing);
   },
@@ -97,60 +99,82 @@ AFRAME.registerComponent("networked-drawing", {
     const normal = new THREE.Vector3();
     const copyArray = [];
     return function() {
-      if (this.bufferIndex < this.drawBuffer.length && NAF.connection.isConnected() && this.networkedEl) {
+      if (!this.connectedToOwner && NAF.connection.isConnected() && this.networkedEl) {
+        const owner = NAF.utils.getNetworkOwner(this.networkedEl);
+        if (!NAF.utils.isMine(this.networkedEl) && NAF.connection.hasActiveDataChannel(owner)) {
+          NAF.connection.sendDataGuaranteed(owner, this.drawingId, {
+            type: MSG_CONFIRM_CONNECT,
+            clientId: NAF.clientId
+          });
+        }
+        this.connectedToOwner = true;
+      }
+
+      if (this.drawBuffer.length > 0 && NAF.connection.isConnected() && this.networkedEl) {
         if (!NAF.utils.isMine(this.networkedEl)) {
-          const head = this.drawBuffer[this.bufferIndex];
-          if (head != null && typeof head === "string") {
+          const head = this.drawBuffer[0];
+          if (head !== null && typeof head === "string") {
             //TODO: check radius and segments as well, somehow
             this.color.set(head);
-          } else if (head != null && this.bufferIndex + 9 <= this.drawBuffer.length) {
-            --this.bufferIndex;
-            position.set(
-              this.drawBuffer[++this.bufferIndex],
-              this.drawBuffer[++this.bufferIndex],
-              this.drawBuffer[++this.bufferIndex]
-            );
-            direction.set(
-              this.drawBuffer[++this.bufferIndex],
-              this.drawBuffer[++this.bufferIndex],
-              this.drawBuffer[++this.bufferIndex]
-            );
-            normal.set(
-              this.drawBuffer[++this.bufferIndex],
-              this.drawBuffer[++this.bufferIndex],
-              this.drawBuffer[++this.bufferIndex]
-            );
+            this.drawBuffer.shift();
+          } else if (head != null && this.drawBuffer.length >= 9) {
+            position.set(this.drawBuffer[0], this.drawBuffer[1], this.drawBuffer[2]);
+            direction.set(this.drawBuffer[3], this.drawBuffer[4], this.drawBuffer[5]);
+            normal.set(this.drawBuffer[6], this.drawBuffer[7], this.drawBuffer[8]);
             if (!this.remoteLineStarted) {
               this.startDraw(position, direction, normal);
               this.remoteLineStarted = true;
             } else {
               this.draw(position, direction, normal);
             }
+            this.drawBuffer.splice(0, 9);
           } else if (head === null) {
             this.endDraw(position, direction, normal);
             this.remoteLineStarted = false;
+            this.drawBuffer.shift();
           }
-          ++this.bufferIndex;
-        } else if (this.drawBuffer.length > 0) {
+        } else if (this.bufferIndex < this.drawBuffer.length) {
           //TODO: don't do this on every tick?
           copyArray.length = 0;
           copyData(this.drawBuffer, copyArray, this.bufferIndex, this.drawBuffer.length - 1);
-          NAF.connection.broadcastDataGuaranteed(this.drawingId, copyArray);
           this.bufferIndex = this.drawBuffer.length;
+          NAF.connection.broadcastDataGuaranteed(this.drawingId, { type: MSG_BUFFER_DATA, buffer: copyArray });
         }
       }
+
+      this.deleteLines();
     };
   })(),
 
+  deleteLines() {
+    if (this.drawBufferHistory.length > 0 && this.drawBufferHistory[0].time + this.data.drawTimeout <= Date.now()) {
+      const datum = this.drawBufferHistory[0];
+      if (this.drawBufferHistory.length > 1) {
+        datum.idxLength += 2 - (this.segments % 2);
+        this.drawBufferHistory[1].idxLength -= 2 - (this.segments % 2);
+      }
+      console.log("remove", datum.idxLength, this.sharedBuffer.idx);
+      this.idx.position = datum.idxLength;
+      this.idx.uv = datum.idxLength;
+      this.idx.normal = datum.idxLength;
+      this.idx.color = datum.idxLength;
+      this.sharedBuffer.remove(this.prevIdx, this.idx);
+      this.drawBufferHistory.shift();
+    }
+  },
+
   sendDrawBuffer: (() => {
     const copyArray = [];
     //This number needs to be approx. < ~6000 based on napkin math
     //see: https://github.com/webrtc/adapter/blob/682e0f2439e139da6c0c406370eae820637b8c1a/src/js/common_shim.js#L157
     const chunkAmount = 3000;
-    return function(evt) {
+    return function(clientId) {
       if (NAF.utils.isMine(this.networkedEl)) {
         if (this.drawBuffer.length <= chunkAmount) {
-          NAF.connection.sendDataGuaranteed(evt.detail.clientId, this.drawingId, this.drawBuffer);
+          NAF.connection.sendDataGuaranteed(clientId, this.drawingId, {
+            type: MSG_BUFFER_DATA,
+            buffer: this.drawBuffer
+          });
         } else {
           //TODO: do this in tick?
           let x = 0;
@@ -158,53 +182,80 @@ AFRAME.registerComponent("networked-drawing", {
             x = Math.min(x + chunkAmount, this.drawBuffer.length);
             copyArray.length = 0;
             copyData(this.drawBuffer, copyArray, x - chunkAmount, x - 1);
-            NAF.connection.sendDataGuaranteed(evt.detail.clientId, this.drawingId, copyArray);
+            NAF.connection.sendDataGuaranteed(clientId, this.drawingId, {
+              type: MSG_BUFFER_DATA,
+              buffer: copyArray
+            });
           }
         }
       }
     };
   })(),
 
-  receiveDrawBuffer(_, dataType, data) {
-    this.drawBuffer.push.apply(this.drawBuffer, data);
+  receiveData(_, dataType, data) {
+    switch (data.type) {
+      case MSG_CONFIRM_CONNECT:
+        this.sendDrawBuffer(data.clientId);
+        break;
+      case MSG_BUFFER_DATA:
+        this.drawBuffer.push.apply(this.drawBuffer, data.buffer);
+        break;
+    }
   },
 
   getLastPoint() {
     return this.lastPoint;
   },
 
-  draw(position, direction, normal) {
+  startDraw(position, direction, normal, color, radius, segments) {
     if (!NAF.connection.isConnected()) {
       return;
     }
 
-    if (!this.lineStarted) {
-      this.addSegments(this.lastSegments, position, direction, normal, this.radius);
-      if (this.initialized) {
-        this.addVertex(this.lastSegments[0]); //discarded
-      }
-      this.drawCap(this.lastPoint, this.lastSegments);
-      this.lineStarted = true;
-    } else {
-      this.addSegments(this.currentSegments, position, direction, normal, this.radius);
-      this.drawCylinder();
+    if (color && color != "#" + this.color.getHex()) {
+      this.color.set(color);
+      this.drawBuffer.push(color);
     }
+    if (radius) this.radius = radius;
+    if (segments) this.segments = segments;
+
     this.lastPoint.copy(position);
     this.addToDrawBuffer(position, direction, normal);
+    this.lastDrawTime = Date.now();
   },
 
-  startDraw(position, direction, normal, color, radius, segments) {
+  draw(position, direction, normal, radiusMultiplier = 1.0) {
     if (!NAF.connection.isConnected()) {
       return;
     }
 
-    if (color && color != "#" + this.color.getHex()) {
-      this.color.set(color);
-      this.drawBuffer.push(color);
-    }
-    if (radius) this.radius = radius;
-    if (segments) this.segments = segments;
+    if (!this.lineStarted) {
+      this.addSegments(this.lastSegments, position, direction, normal, this.radius * radiusMultiplier);
+
+      if (this.drawBufferHistory.length === 0) {
+        //start with CW faceculling order
+        this.addDegenerateTriangle();
+      } else {
+        //only do the following if the sharedBuffer is not empty
+        this.restartPrimitive();
+        this.addDegenerateTriangle();
+        if (this.segments % 2 === 0) {
+          //flip faceculling order if even numbered segments
+          this.addDegenerateTriangle();
+        }
+      }
+
+      this.drawCap(this.lastPoint, this.lastSegments);
+      if (this.segments % 2 !== 0) {
+        //flip faceculling order if odd numbered segments
+        this.addDegenerateTriangle();
+      }
 
+      this.lineStarted = true;
+    } else {
+      this.addSegments(this.currentSegments, position, direction, normal, this.radius * radiusMultiplier);
+      this.drawCylinder(position);
+    }
     this.lastPoint.copy(position);
     this.addToDrawBuffer(position, direction, normal);
   },
@@ -223,12 +274,22 @@ AFRAME.registerComponent("networked-drawing", {
         this.draw(position, direction, normal);
         projectedDirection.copy(direction).multiplyScalar(this.radius);
         projectedPoint.copy(position).add(projectedDirection);
+
+        //flip faceculling order before drawing end-cap
+        this.addDegenerateTriangle();
+
         this.drawCap(projectedPoint, this.lastSegments);
       }
 
-      if (this.networkedEl && NAF.utils.isMine(this.networkedEl)) {
+      if (this.lineStarted && this.networkedEl && NAF.utils.isMine(this.networkedEl)) {
         this.drawBuffer.push(null);
+        this.drawBufferHistory.push({
+          drawBufferIndex: this.drawBuffer.length,
+          idxLength: this.vertexCount - 1,
+          time: Date.now()
+        });
       }
+      this.vertexCount = 0;
       this.lineStarted = false;
     };
   })(),
@@ -248,17 +309,12 @@ AFRAME.registerComponent("networked-drawing", {
   },
 
   //draw a cylinder from last to current segments
-  drawCylinder() {
-    this.addVertex(this.lastSegments[0]); //discarded
+  drawCylinder(position) {
     for (let i = 0; i != this.segments + 1; i++) {
-      this.addVertex(this.lastSegments[i % this.segments]);
-      this.addVertex(this.currentSegments[i % this.segments]);
+      this.addVertex(this.lastSegments[i % this.segments], position);
+      this.addVertex(this.currentSegments[i % this.segments], position);
     }
-
-    this.sharedBuffer.restartPrimitive();
-
     this.sharedBuffer.update();
-
     for (let j = 0; j < this.segments; j++) {
       this.lastSegments[j].copy(this.currentSegments[j]);
     }
@@ -272,24 +328,24 @@ AFRAME.registerComponent("networked-drawing", {
     const projectedDirection = new THREE.Vector3();
     const projectedPoint = new THREE.Vector3();
     return function(position) {
-      projectedDirection.copy(up).multiplyScalar(this.radius * 0.5);
-      projectedPoint.copy(position).add(projectedDirection);
-      this.addSegments(this.lastSegments, projectedPoint, up, left, this.radius * 0.5);
-      if (this.initialized) {
-        this.addVertex(this.lastSegments[0]); //discarded
-      }
       projectedDirection.copy(up).multiplyScalar(this.radius * 0.75);
       projectedPoint.copy(position).add(projectedDirection);
-      this.drawCap(projectedPoint, this.lastSegments);
-      this.addVertex(this.lastSegments[0]); //discared
-      this.addSegments(this.currentSegments, position, up, left, this.radius * 0.75);
-      this.drawCylinder();
+      this.lastPoint.copy(projectedPoint);
+
+      projectedDirection.copy(up).multiplyScalar(this.radius * 0.5);
+      projectedPoint.copy(position).add(projectedDirection);
+      this.draw(projectedPoint, down, left, 0.75);
+
+      this.draw(position, down, left);
+
       projectedDirection.copy(down).multiplyScalar(this.radius * 0.5);
       projectedPoint.copy(position).add(projectedDirection);
-      this.addSegments(this.currentSegments, projectedPoint, up, left, this.radius * 0.5);
-      this.drawCylinder();
+      this.draw(projectedPoint, down, left, 0.75);
+
       projectedDirection.copy(down).multiplyScalar(this.radius * 0.75);
       projectedPoint.copy(position).add(projectedDirection);
+
+      this.addDegenerateTriangle(); //discarded
       this.drawCap(projectedPoint, this.lastSegments);
     };
   })(),
@@ -297,22 +353,48 @@ AFRAME.registerComponent("networked-drawing", {
   //draw a cap to start/end a line
   drawCap(point, segments) {
     let segmentIndex = 0;
-    for (let i = 0; i < this.segments + 4; i++) {
-      if ((i - 1) % 4 === 0) {
+    for (let i = 0; i < this.segments * 2 - (this.segments % 2); i++) {
+      if ((i - 2) % 4 === 0) {
         this.addVertex(point);
       } else {
         this.addVertex(segments[segmentIndex % this.segments]);
-        ++segmentIndex;
+        if ((i + 1) % 5 !== 0) {
+          ++segmentIndex;
+        }
       }
     }
-    this.sharedBuffer.restartPrimitive();
     this.sharedBuffer.update();
   },
 
-  addVertex(point) {
-    this.initialized = true;
-    this.sharedBuffer.addVertex(point.x, point.y, point.z);
-    this.sharedBuffer.addColor(this.color.r, this.color.g, this.color.b);
+  restartPrimitive() {
+    this.sharedBuffer.restartPrimitive();
+    ++this.vertexCount;
+    console.log("restartPrimitive", this.vertexCount);
+  },
+
+  addVertex: (() => {
+    const normal = new THREE.Vector3();
+    return function(point, position) {
+      this.sharedBuffer.addVertex(point.x, point.y, point.z);
+      this.sharedBuffer.addColor(this.color.r, this.color.g, this.color.b);
+      if (position) {
+        normal.subVectors(point, position).normalize();
+        this.sharedBuffer.addNormal(normal.x, normal.y, normal.z);
+      } else {
+        ++this.sharedBuffer.idx.normal;
+      }
+
+      ++this.sharedBuffer.idx.uv;
+      ++this.vertexCount;
+      console.error("addVertex", point.x, point.y, point.z, this.vertexCount);
+
+      //TODO: normals
+    };
+  })(),
+
+  addDegenerateTriangle() {
+    console.error("addDegenerateTriangle");
+    this.addVertex(this.lastSegments[0]);
   },
 
   //calculate the segments for a given point
diff --git a/src/components/tools/pen.js b/src/components/tools/pen.js
index cbd1407beed3beb32f08e55b283e2c6b461ed4db..ba7610487b3e7a12a8f51c26763e6419a3f39c70 100644
--- a/src/components/tools/pen.js
+++ b/src/components/tools/pen.js
@@ -10,21 +10,17 @@ function almostEquals(epsilon, u, v) {
 AFRAME.registerComponent("pen", {
   schema: {
     drawFrequency: { default: 20 },
-    minDistanceBetweenPoints: { default: 0.04 },
+    minDistanceBetweenPoints: { default: 0.4 },
     defaultDirection: { default: { x: 1, y: 0, z: 0 } },
     camera: { type: "selector" },
     drawing: { type: "string" },
-    useMouse: { defualt: false }
+    drawingManager: { type: "string" }
   },
 
   init() {
-    this.onMouseDown = this.onMouseDown.bind(this);
-    this.onMouseUp = this.onMouseUp.bind(this);
-
     this.startDraw = this.startDraw.bind(this);
     this.endDraw = this.endDraw.bind(this);
 
-    this.isDrawing = false;
     this.timeSinceLastDraw = 0;
 
     this.lastPosition = new THREE.Vector3();
@@ -33,68 +29,41 @@ AFRAME.registerComponent("pen", {
     this.direction = new THREE.Vector3();
     this.direction.copy(this.data.defaultDirection);
 
-    this.handleDrawingInitialized = this.handleDrawingInitialized.bind(this);
-
-    this.drawing = document.querySelector(this.data.drawing);
-
-    if (this.drawing.hasLoaded) {
-      this.currentDrawing = this.drawing.components["networked-drawing"];
-    } else {
-      this.drawing.addEventListener("componentinitialized", this.handleDrawingInitialized);
-    }
+    this.currentDrawing = null;
 
     this.normal = new THREE.Vector3();
 
     this.worldPosition = new THREE.Vector3();
   },
 
-  remove() {
-    this.drawing.removeEventListener("componentinitialized", this.handleDrawingInitialized);
-  },
-
   play() {
-    // if (this.data.useMouse && false) {
-    //   document.addEventListener("mousedown", this.onMouseDown);
-    //   document.addEventListener("mouseup", this.onMouseUp);
-    // }
+    this.drawingManager = document.querySelector(this.data.drawingManager).components["drawing-manager"];
 
-    // this.el.parentNode.addEventListener("index_down", this.startDraw);
-    // this.el.parentNode.addEventListener("index_up", this.endDraw);
-
-    if (!this.data.useMouse) {
-      this.el.parentNode.addEventListener("activate-start", this.startDraw);
-      this.el.parentNode.addEventListener("activate-end", this.endDraw);
-    }
+    this.el.parentNode.addEventListener("activate-start", this.startDraw);
+    this.el.parentNode.addEventListener("activate-end", this.endDraw);
   },
 
   pause() {
-    document.removeEventListener("mousedown", this.onMouseDown);
-    document.removeEventListener("mouseup", this.onMouseUp);
-
-    this.el.parentNode.removeEventListener("index_down", this.startDraw);
-    this.el.parentNode.removeEventListener("index_up", this.endDraw);
-
     this.el.parentNode.removeEventListener("activate-start", this.startDraw);
     this.el.parentNode.removeEventListener("activate-end", this.endDraw);
   },
 
   tick(t, dt) {
     this.el.object3D.getWorldPosition(this.worldPosition);
-    const drawing = this.currentDrawing;
 
     if (!almostEquals(0.005, this.worldPosition, this.lastPosition)) {
       this.direction.subVectors(this.worldPosition, this.lastPosition).normalize();
       this.lastPosition.copy(this.worldPosition);
     }
 
-    if (drawing && this.isDrawing) {
+    if (this.currentDrawing) {
       const time = this.timeSinceLastDraw + dt;
       if (
         time >= this.data.drawFrequency &&
-        drawing.getLastPoint().distanceTo(this.worldPosition) >= this.data.minDistanceBetweenPoints
+        this.currentDrawing.getLastPoint().distanceTo(this.worldPosition) >= this.data.minDistanceBetweenPoints
       ) {
         this.getNormal(this.normal, this.worldPosition, this.direction);
-        drawing.draw(this.worldPosition, this.direction, this.normal);
+        this.currentDrawing.draw(this.worldPosition, this.direction, this.normal);
       }
 
       this.timeSinceLastDraw = time % this.data.drawFrequency;
@@ -104,56 +73,47 @@ AFRAME.registerComponent("pen", {
   //helper function to get normal of direction of drawing cross direction to camera
   getNormal: (() => {
     const directionToCamera = new THREE.Vector3();
-    const worldQuaternion = new THREE.Quaternion();
+    // const worldQuaternion = new THREE.Quaternion();
     return function(normal, position, direction) {
-      if (this.data.camera) {
-        directionToCamera.subVectors(position, this.data.camera.object3D.position).normalize();
-        normal.crossVectors(direction, directionToCamera);
-      } else {
-        //TODO remove?
-        this.el.object3D.getWorldQuaternion(worldQuaternion);
-        normal
-          .copy(this.el.object3D.up)
-          .applyQuaternion(worldQuaternion)
-          .normalize();
-      }
+      // if (this.data.camera) {
+      directionToCamera.subVectors(position, this.data.camera.object3D.position).normalize();
+      normal.crossVectors(direction, directionToCamera);
+      // normal.set(normal.x, Math.abs(normal.y), normal.z);
+      // console.log(normal);
+      // } else {
+      //TODO remove?
+      // this.el.object3D.getWorldQuaternion(worldQuaternion);
+      // normal
+      //   .copy(this.el.object3D.up)
+      //   .applyQuaternion(worldQuaternion)
+      //   .normalize();
+      // }
     };
   })(),
 
-  handleDrawingInitialized(e) {
-    if (e.detail.name === "networked-drawing") {
-      this.currentDrawing = this.drawing.components["networked-drawing"];
-    }
-  },
-
-  onMouseDown(e) {
-    if (this.currentDrawing && e.button === 0) {
-      this.startDraw();
-    }
-  },
-
-  onMouseUp(e) {
-    if (this.currentDrawing && e.button === 0) {
-      this.endDraw();
-    }
-  },
-
   startDraw() {
-    this.isDrawing = true;
-    this.el.object3D.getWorldPosition(this.worldPosition);
-    this.getNormal(this.normal, this.worldPosition, this.direction);
-    const color = "#" + Math.floor(Math.random() * 16777215).toString(16);
-    this.el.setAttribute("material", { color: color });
-    this.currentDrawing.startDraw(this.worldPosition, this.direction, this.normal, color);
+    this.currentDrawing = this.drawingManager.getDrawing(this);
+    if (this.currentDrawing) {
+      this.el.object3D.getWorldPosition(this.worldPosition);
+      this.getNormal(this.normal, this.worldPosition, this.direction);
+      const color =
+        "#" +
+        Math.random()
+          .toString(16)
+          .slice(2, 8);
+      this.el.setAttribute("material", { color: color });
+      this.currentDrawing.startDraw(this.worldPosition, this.direction, this.normal, color);
+    }
   },
 
   endDraw() {
-    if (this.isDrawing) {
-      this.isDrawing = false;
+    if (this.currentDrawing) {
       this.timeSinceLastDraw = 0;
       this.el.object3D.getWorldPosition(this.worldPosition);
       this.getNormal(this.normal, this.worldPosition, this.direction);
       this.currentDrawing.endDraw(this.worldPosition, this.direction, this.normal);
+      this.drawingManager.returnDrawing(this);
+      this.currentDrawing = null;
     }
   }
 });
diff --git a/src/hub.html b/src/hub.html
index ea17335f6d9fac186b55b23240fc0d3d02493c3e..dcb69281d7d68e896a32bc03a587cdf31149347c 100644
--- a/src/hub.html
+++ b/src/hub.html
@@ -211,7 +211,7 @@
                         position="0 -0.18 0" 
                         radius="0.02" 
                         color="red" 
-                        pen="camera: #player-camera; drawing: #my-first-drawing;"
+                        pen="camera: #player-camera; drawingManager: #drawing-manager"
                     ></a-sphere>
                 </a-entity>
             </template>
@@ -266,6 +266,8 @@
 
         <a-entity id="pen-counter" networked-counter="max: 3;"></a-entity>
 
+        <a-entity id="drawing-manager" drawing-manager="drawing: #my-first-drawing;"></a-entity>
+
         <a-entity
             id="cursor-controller"
             cursor-controller="
diff --git a/src/hub.js b/src/hub.js
index 8df7a69f9e93a54ab9de5176bf54615af971a1b8..e869eec93d230f49621ac6030bb6b6e16bfceabe 100644
--- a/src/hub.js
+++ b/src/hub.js
@@ -134,6 +134,7 @@ import ConcurrentLoadDetector from "./utils/concurrent-load-detector.js";
 
 import "./components/tools/pen";
 import "./components/tools/networked-drawing";
+import "./components/tools/drawing-manager";
 
 function qsTruthy(param) {
   const val = qs.get(param);
diff --git a/src/vendor/sharedbuffergeometry.js b/src/vendor/sharedbuffergeometry.js
index 343a77b078aa03dab2ae4154408dbc42fd1167bd..0f8f0985bb5c17ef1dda3fea52295401265be0e6 100644
--- a/src/vendor/sharedbuffergeometry.js
+++ b/src/vendor/sharedbuffergeometry.js
@@ -11,14 +11,10 @@ export default class SharedBufferGeometry {
     this.addBuffer(false);
   }
 
-  getDrawing () {
-    return this.drawing;
-  }
-
   restartPrimitive () {
     if (this.idx.position >= this.current.attributes.position.count) {
       this.addBuffer(false);
-    } else if (this.idx.position !== 0) {
+    } else if (this.idx.position !== 0) {   
       let prev = (this.idx.position - 1) * 3;
       const position = this.current.attributes.position.array;
       this.addVertex(position[prev++], position[prev++], position[prev++]);
@@ -30,7 +26,7 @@ export default class SharedBufferGeometry {
   }
 
   remove (prevIdx, idx) {
-    const pos = this.current.attributes.position.array;
+    // const pos = this.current.attributes.position.array;
 
     // Loop through all the attributes: position, color, uv, normal,...
     if (this.idx.position > idx.position) {
@@ -41,14 +37,26 @@ export default class SharedBufferGeometry {
         const end = this.idx[key] * componentSize;
         for (let i = start; i < end; i++) {
           this.current.attributes[key].array[pos++] = this.current.attributes[key].array[i];
+          // this.current.attributes[key].array[i] = Number.NEGATIVE_INFINITY;
         }
+        const diff = (idx[key] - prevIdx[key] + 1);
+        this.idx[key] -= diff;
       }
-    }
+    } else {
+      for (let key in this.idx) {
+        // const componentSize = key === 'uv' ? 2 : 3;
+        // for (let i = 0; i < this.idx.position * componentSize; i++) {
+        //     this.current.attributes[key].array[i] = Number.NEGATIVE_INFINITY;
+        // }
+        const diff = (idx[key] - prevIdx[key]);
+        this.idx[key] -= diff;
+      }
+    } 
 
-    for (key in this.idx) {
-      const diff = (idx[key] - prevIdx[key]);
-      this.idx[key] -= diff;
-    }
+    // for (let key in this.idx) {
+      // const diff = (idx[key] - prevIdx[key]);
+      // this.idx[key] -= diff;
+    // }
 
     this.update();
   }
@@ -59,6 +67,7 @@ export default class SharedBufferGeometry {
   }
 
   addBuffer (copyLast) {
+    console.log("addBuffer", copyLast)
     const geometry = new THREE.BufferGeometry();
 
     const vertices = new Float32Array(this.maxBufferSize * 3);