diff --git a/index.html b/index.html
index e14d6ad7d7aefa87254e0f89032bdb57b21ceeb5..22a70d6fba24ba4b6aee48a9e9d2f7005c7add32 100644
--- a/index.html
+++ b/index.html
@@ -85,6 +85,7 @@
     <script src="js/models/BasePlane.js"></script>
     <script src="js/models/extrudeVisualizer.js"></script>
     <script src="js/models/AppState.js"></script>
+    <script src="js/cam/assemblers/Component.js"></script>
     <script src="js/cam/assemblers/Assembler.js"></script>
     <script src="js/cam/MachineOneBit.js"></script>
     <script src="js/cam/assemblers/StaplerAssembler.js"></script>
diff --git a/js/cam/assemblers/Assembler.js b/js/cam/assemblers/Assembler.js
index bc88c628b7fe5b0ef212edbf9d9ed7f2351701aa..dafd50ede1e67323554c2f511869ad365f835a8c 100644
--- a/js/cam/assemblers/Assembler.js
+++ b/js/cam/assemblers/Assembler.js
@@ -3,7 +3,7 @@
  */
 
 
-var assemblerMaterial = new THREE.MeshLambertMaterial({color:0xaaaaaa, shading: THREE.FlatShading, transparent:true, opacity:1});
+var assemblerMaterial = new THREE.MeshLambertMaterial({color:0xaaaaaa, shading: THREE.FlatShading, transparent:true, opacity:0.5});
 
 function Assembler(){
 
@@ -12,7 +12,7 @@ function Assembler(){
     this.object3D = new THREE.Object3D();
     globals.three.sceneAdd(this.object3D);
     var self = this;
-    this._buildAssemblerMeshes(function(){
+    this._buildAssemblerComponents(function(){
         self._configureAssemblerMovementDependencies();
         globals.three.render();
     });
@@ -26,7 +26,7 @@ Assembler.prototype._buildStock = function(){
 Assembler.prototype._positionStockRelativeToEndEffector = function(){
 };
 
-Assembler.prototype._buildAssemblerMeshes = function(callback){
+Assembler.prototype._buildAssemblerComponents = function(callback){
     var numMeshes = this._getTotalNumMeshes();
     if (numMeshes == 0) {
         callback();
@@ -40,7 +40,7 @@ Assembler.prototype._buildAssemblerMeshes = function(callback){
 
     var self = this;
     function doAdd(geometry, name){
-        self[name] = new THREE.Mesh(geometry, assemblerMaterial);
+        self[name] = new Component(geometry, assemblerMaterial);
         if (allLoaded()) callback();
     }
 
@@ -56,9 +56,19 @@ Assembler.prototype._configureAssemblerMovementDependencies = function(){
 
 Assembler.prototype.setVisibility = function(visible){
     this.object3D.visible = visible;
+    this._setTranslucent();
     globals.three.render();
 };
 
+Assembler.prototype._setTranslucent = function(){
+    //todo make stock transparent
+    if (globals.appState.get("currentTab") == "cam"){
+        assemblerMaterial.transparent = true;
+    } else {
+        assemblerMaterial.transparent = false;
+    }
+};
+
 
 
 
@@ -165,29 +175,11 @@ Assembler.prototype._moveTo = function(x, y, z, speed, wcs, callback){
         if (totalThreads > 0) return;
         callback();
     }
-    var startingPos = this.stock.getPosition();
+    var startingPos = {x:this.xAxis.getPosition(), y:this.yAxis.getPosition(), z:this.zAxis.getPosition()};
     speed = this._normalizeSpeed(startingPos, x, y, this._reorganizeSpeed(speed));
-    this._moveXAxis(startingPos.x, x, speed.x, sketchyCallback);
-    this._moveYAxis(startingPos.y, y, speed.y, sketchyCallback);
-    this._moveZAxis(startingPos.z, z, speed.z, sketchyCallback);
-};
-
-Assembler.prototype._moveXAxis = function(startingPos, target, speed, callback){
-    this._moveAxis(startingPos, target, "x", speed, callback);
-};
-Assembler.prototype._moveYAxis = function(startingPos, target, speed, callback){
-    this._moveAxis(startingPos, target, "y", speed, callback);
-};
-Assembler.prototype._moveZAxis = function(startingPos, target, speed, callback){
-    this._moveAxis(startingPos, target, "z", speed, callback);
-};
-
-Assembler.prototype._moveAxis = function(startingPos, target, axis, speed, callback){
-    if (target == null || target === undefined) {
-        callback();
-        return;
-    }
-    this._animateObjects([this.stock], axis, speed, startingPos, target, callback);
+    this.xAxis.moveTo(this._makeAxisVector(x, "x"), speed.x, sketchyCallback);
+    this.yAxis.moveTo(this._makeAxisVector(y, "y"), speed.y, sketchyCallback);
+    this.zAxis.moveTo(this._makeAxisVector(z, "z"), speed.z, sketchyCallback);
 };
 
 Assembler.prototype._makeAbsPosition = function(target, wcs){
@@ -216,39 +208,20 @@ Assembler.prototype._normalizeSpeed = function(startingPos, x, y, speed){//xy mo
     return normSpeed;
 };
 
-Assembler.prototype._animateObjects = function(objects, axis, speed, startingPos, target, callback){
-    var increment = speed/25*globals.cam.get("simSpeed");
-    if (increment == 0) {
-        if (callback) callback();
-        return;
+Assembler.prototype._makeAxisVector = function(position, axis){
+    switch (axis){
+        case "x":
+            return {x:position, y:0, z:0};
+        case "y":
+            return {x:0, y:position, z:0};
+        case "z":
+            return {x:0, y:0, z:position};
+        default:
+            console.warn(axis + " axis not recognized");
+            return null;
     }
-    var direction = 1;
-    if (target-startingPos < 0) direction = -1;
-    increment = Math.max(increment, 0.00001)*direction;//need to put a min on the increment - other wise this stall out with floating pt tol
-    this._incrementalMove(objects, axis, increment, startingPos, target, direction, callback);
-};
-
-Assembler.prototype._incrementalMove = function(objects, axis, increment, currentPos, target, direction, callback){
-    var self = this;
-    setTimeout(function(){
-        if ((target-currentPos)*direction <= 0) {
-            if (callback) callback();
-            return;
-        }
-        var nextPos = currentPos + increment;
-        if (Math.abs(target-currentPos) < Math.abs(increment)) nextPos = target;//don't overshoot
-        self._setPosition(objects, nextPos, axis);
-        self._incrementalMove(objects, axis, increment, nextPos, target, direction, callback)
-    }, 10);
 };
 
-Assembler.prototype._setPosition = function(objects, nextPos, axis){
-    _.each(objects, function(object){
-        object.position[axis] = nextPos;
-    });
-};
-
-
 
 
 
@@ -256,11 +229,11 @@ Assembler.prototype._setPosition = function(objects, nextPos, axis){
 
 Assembler.prototype.destroy = function(){
     this.stock.destroy();
-    this.zAxis.parent.remove(this.zAxis);
-    this.xAxis.parent.remove(this.xAxis);
-    this.yAxis.parent.remove(this.yAxis);
-    this.frame.parent.remove(this.frame);
-    this.substrate.parent.remove(this.substrate);
+    this.zAxis.destroy();
+    this.xAxis.destroy();
+    this.yAxis.destroy();
+    this.frame.destroy();
+    this.substrate.destroy();
     globals.three.sceneRemove(this.object3D);
     this.stock = null;
     this.zAxis = null;
diff --git a/js/cam/assemblers/Component.js b/js/cam/assemblers/Component.js
new file mode 100644
index 0000000000000000000000000000000000000000..207f91e0fd187e57ad95f352a64d6f691bae86f1
--- /dev/null
+++ b/js/cam/assemblers/Component.js
@@ -0,0 +1,89 @@
+/**
+ * Created by aghassaei on 5/28/15.
+ */
+
+
+function Component(geometry, material){
+    this.object3D = new THREE.Mesh(geometry, material);
+}
+
+Component.prototype.getPosition = function(){
+    return this.object3D.position.clone();
+};
+
+Component.prototype.getObject3D = function(){
+    return this.object3D;
+};
+
+Component.prototype.addChild = function(child){
+    this.object3D.add(child.getObject3D());
+};
+
+Component.prototype.moveTo = function(target, speed, callback){
+    var currentPosition = this.getPosition();
+    var diff = _.clone(target);
+    _.each(_.keys(target), function(key){
+        diff[key] -= currentPosition[key];
+    });
+
+    var diffLength = this._getLength(diff);
+    var increment = speed/25*globals.cam.get("simSpeed");
+
+    if (increment == 0 || diffLength == 0) {
+        if (callback) callback();
+        return;
+    }
+    increment = Math.max(increment, 0.00001);//need to put a min on the increment - otherwise this stalls out with floating pt tol
+
+    var incrementVector = diff;
+    _.each(_.keys(incrementVector), function(key){
+        incrementVector[key] *= increment/diffLength;
+    });
+
+    this._incrementalMove(incrementVector, target, callback);
+};
+
+Component.prototype._remainingDistanceToTarget = function(target){
+    var position = this.getPosition();
+    var dist = 0;
+    _.each(_.keys(target), function(key){
+        dist += Math.pow(target[key] - position[key], 2);
+    });
+    return dist;
+};
+
+Component.prototype._getLength = function(vector){
+    var length = 0;
+    _.each(_.keys(vector), function(key){
+        length += Math.pow(vector[key], 2);
+    });
+    return length;
+};
+
+Component.prototype._incrementalMove = function(increment, target, callback){
+    var self = this;
+    setTimeout(function(){
+        var remainingDist = Math.abs(self._remainingDistanceToTarget(target));
+        var nextPos;
+        if (remainingDist == 0) {
+            if (callback) callback();
+            return;
+        } else if (remainingDist < self._getLength(increment)){
+            nextPos = target;//don't overshoot
+        } else {
+            nextPos = self.getPosition();
+            _.each(_.keys(nextPos), function(key){
+                nextPos[key] += increment[key];
+            });
+        }
+
+        console.log(nextPos);
+        self.object3D.position.set(nextPos.x, nextPos.y, nextPos.z);
+        self._incrementalMove(increment, target, callback);
+    }, 10);
+};
+
+Component.prototype.destroy = function(){
+    if (this.object3D && this.object3D.parent) this.object3D.parent.remove(this.object3D);
+    this.object3D = null;
+};
\ No newline at end of file
diff --git a/js/cam/assemblers/StaplerAssembler.js b/js/cam/assemblers/StaplerAssembler.js
index b815ec6e3b263b89b83ab14e40f8c9af82bb8aa5..0cecf97785e0851891106eca7f8e4ba072186f52 100644
--- a/js/cam/assemblers/StaplerAssembler.js
+++ b/js/cam/assemblers/StaplerAssembler.js
@@ -15,12 +15,12 @@ StaplerAssembler.prototype._positionStockRelativeToEndEffector = function(stock)
 };
 
 StaplerAssembler.prototype._configureAssemblerMovementDependencies = function(){
-    this.zAxis.add(this.stock.getObject3D());
-    this.xAxis.add(this.zAxis);
-    this.frame.add(this.xAxis);
-    this.frame.add(this.yAxis);
-    this.object3D.add(this.frame);
-    this.object3D.add(this.substrate);
+    this.zAxis.addChild(this.stock);
+    this.xAxis.addChild(this.zAxis);
+    this.frame.addChild(this.xAxis);
+    this.frame.addChild(this.yAxis);
+    this.object3D.add(this.frame.getObject3D());
+    this.object3D.add(this.substrate.getObject3D());
 };
 
 StaplerAssembler.prototype._getTotalNumMeshes = function(){
diff --git a/js/cam/cam.js b/js/cam/cam.js
index 00cd7fb60cfcd6e3917b175688ca4ca776ce637b..c088912db8e0f7f580abd5fffff894a10f53c76d 100644
--- a/js/cam/cam.js
+++ b/js/cam/cam.js
@@ -82,6 +82,7 @@ Cam = Backbone.Model.extend({
         if (this.get("assembler")) this.get("assembler").destroy();
         this.set("assembler", null);
         this._setMachineDefaults(machineName);
+        globals.appState.set("basePlaneIsVisible", false);
         if (machineName == "shopbot"){
             this.set("assembler", new Shopbot());
         } else if (machineName == "handOfGod"){
@@ -145,6 +146,7 @@ Cam = Backbone.Model.extend({
 //        this.get("stock").visible = visible;
         if (visible && !this.get("assembler")) this.selectMachine();
         if (this.get("assembler")) this.get("assembler").setVisibility(visible);
+        if (globals.appState.get("currentNav") == "navAssemble") globals.appState.set("basePlaneIsVisible", !visible);
         globals.three.render();
     },
 
@@ -166,7 +168,7 @@ Cam = Backbone.Model.extend({
 
     _moveOrigin: function(){
         var position = this.get("originPosition");
-        this.get("origin").position.set(position.x, position.y, position.z);
+//        this.get("origin").position.set(position.x, position.y, position.z);
         if (this.get("stockFixed")) this._updateStockPosToOrigin(position, this.previous("originPosition"));
         globals.three.render();
         if (this.get("assembler") && this.get("assembler").setMachinePosition) this.get("assembler").setMachinePosition();
diff --git a/js/models/AppState.js b/js/models/AppState.js
index 0e42176c59c4e875fc01c9210775210a84b22344..2d620fc5af9c9735acda266320aa3a49790a3a43 100644
--- a/js/models/AppState.js
+++ b/js/models/AppState.js
@@ -100,11 +100,9 @@ AppState = Backbone.Model.extend({
         }
         else if (navSelection == "navSim") {
             this.set("currentTab", this.get("lastSimulationTab"));
-            this.set("basePlaneIsVisible", false);
         }
         else if (navSelection == "navAssemble") {
             this.set("currentTab", this.get("lastAssembleTab"));
-            this.set("basePlaneIsVisible", false);
         }
     },