diff --git a/css/main.css b/css/main.css
index 46d1b0542e835e7c4207fa2eb816d07bbc13aba2..726fd36536282b22246ca1dfd93f503eedae5d73 100644
--- a/css/main.css
+++ b/css/main.css
@@ -309,3 +309,13 @@ svg{
 #aboutStiffness{
     line-height: 28px;
 }
+
+#start, #stepForwardOptions{
+    display: none;
+}
+#reset{
+    margin-left: 20px;
+}
+#stepForward{
+    margin-left: 13px;
+}
diff --git a/index.html b/index.html
index e0659f228c785aea827128ff65fc1c99b00b1317..e30e6850600519b39af75db70af4035a74a49992 100644
--- a/index.html
+++ b/index.html
@@ -460,8 +460,18 @@
     <div class="indent">
         <label>Average node error: <span id="globalError"></span></label>
         <a class="about floatRight" href="#" id="aboutError"><span class="fui-question-circle"></span></a>
+    </div><br/>
+    <b>Animation Settings:</b><br/>
+    <span class="floatRight">&Delta; t = <span id="deltaT"></span> seconds</span><br/><br/>
+    <a href="#" id="reset" class="btn btn-lg btn-default">Reset</a>
+    <a href="#" id="start" class="btn btn-lg btn-success">Start Simulation</a>
+    <a href="#" id="pause" class="btn btn-lg btn-warning">Pause Simulation</a>
+    <br/><br/>
+    <div id="stepForwardOptions" class="floatRight">
+        Num Steps: &nbsp;&nbsp;<input id="numSteps" value="100" placeholder="" class="form-control" type="text">
+        <a href="#" id="stepForward" class="btn btn-lg btn-default">Step Forward</a>
     </div>
-
+    <br/><br/>
     <div class="extraSpace"></div>
 </div>
 <div id="svgViewer"></div>
diff --git a/js/controls.js b/js/controls.js
index 6644fd9382e610bebdeeb43b8c2addbfba720043..44ddae324487abfa98cd2c433ab372544cc334d4 100644
--- a/js/controls.js
+++ b/js/controls.js
@@ -409,6 +409,32 @@ function initControls(globals){
         $("#aboutAxialStrainModal").modal("show");
     });
 
+    setLink("#start", function(){
+        $("#pause").show();
+        $("#reset").show();
+        $("#start").hide();
+        $("#stepForwardOptions").hide();
+        globals.model.resume();
+    });
+    setLink("#pause", function(){
+        $("#start").show();
+        $("#stepForwardOptions").show();
+        $("#pause").hide();
+        globals.model.pause();
+    });
+    setLink("#reset", function(){
+        if (!globals.threeView.running()) $("#reset").hide();
+        globals.model.reset();
+    });
+    setLink("#stepForward", function(){
+        var numSteps = $("#numSteps").val();
+        numSteps = parseInt(numSteps);
+        if (isNaN(numSteps)) return;
+        if (numSteps<=0) return;
+        $("#numSteps").val(numSteps);
+        globals.model.step(numSteps);
+    });
+
     setInput("#strainClip", globals.strainClip, function(val){
         globals.strainClip = val;
     }, 0.0001, 100);
diff --git a/js/dynamic/dynamicSolver.js b/js/dynamic/dynamicSolver.js
index 9f470c02915f782a76d41dff21ba8fa72e3cbfa9..1ac2be198649838b63dc2e4f7bda46c577c93e10 100644
--- a/js/dynamic/dynamicSolver.js
+++ b/js/dynamic/dynamicSolver.js
@@ -61,6 +61,7 @@ function initDynamicSolver(globals){
         globals.gpuMath.step("zeroTexture", [], "u_lastPosition");
         globals.gpuMath.step("zeroTexture", [], "u_velocity");
         globals.gpuMath.step("zeroTexture", [], "u_lastVelocity");
+        render();
         //todo zero thetas
         // for (var i=0;i<creases.length;i++){
         //     lastTheta[i*4] = 0;
@@ -68,10 +69,9 @@ function initDynamicSolver(globals){
         // }
     }
 
-    function solve(){
+    function solve(_numSteps){
         if (globals.shouldSyncWithModel){
             syncNodesAndEdges();
-            // reset();
             globals.shouldSyncWithModel = false;
         } else {
             if (globals.forceHasChanged) {
@@ -94,17 +94,14 @@ function initDynamicSolver(globals){
                 updateMaterials();
                 globals.materialHasChanged = false;
             }
-            if (globals.shouldResetDynamicSim) {
-                reset();
-                globals.shouldResetDynamicSim = false;
-            }
             if (globals.shouldChangeCreasePercent) {
                 setCreasePercent(globals.creasePercent);
                 globals.shouldChangeCreasePercent = false;
             }
         }
 
-        for (var j=0;j<steps;j++){
+        if (_numSteps == undefined) _numSteps = steps;
+        for (var j=0;j<_numSteps;j++){
             solveStep();
         }
         render();
@@ -200,6 +197,7 @@ function initDynamicSolver(globals){
 
     function setSolveParams(){
         var dt = calcDt()/10;//todo factor of ten?
+        $("#deltaT").html(dt);
         var numSteps = 0.5/dt;
         globals.gpuMath.setProgram("thetaCalc");
         globals.gpuMath.setUniformForProgram("thetaCalc", "u_dt", dt, "1f");
@@ -494,6 +492,7 @@ function initDynamicSolver(globals){
     return {
         syncNodesAndEdges: syncNodesAndEdges,
         updateFixed: updateFixed,
-        solve: solve
+        solve: solve,
+        reset: reset
     }
 }
\ No newline at end of file
diff --git a/js/globals.js b/js/globals.js
index 196a06b2f02a6b368bedf390f7fa44c0c8e7ee66..fee43b73c26d2b8f1b8b9e4938549bea18236c9e 100644
--- a/js/globals.js
+++ b/js/globals.js
@@ -52,7 +52,8 @@ function initGlobals(){
         //save stl settings
         filename: null,
         extension: null,
-        doublesidedSTL: false
+        doublesidedSTL: false,
+        scale: 1
 
     };
 
diff --git a/js/model.js b/js/model.js
index 58a827755678cda5a702a5e01c31318cf5efeb30..48cc0faae1ef6060d73328037944127adf91cee2 100644
--- a/js/model.js
+++ b/js/model.js
@@ -126,6 +126,32 @@ function initModel(globals){
         startSolver();
     }
 
+    function reset(){
+        if (globals.simType == "dynamic"){
+            globals.dynamicSolver.reset();
+        } else {
+            globals.staticSolver.reset();
+        }
+        setGeoUpdates();
+        globals.threeView.render();
+    }
+
+    function step(numSteps){
+        if (globals.simType == "dynamic"){
+            globals.dynamicSolver.solve(numSteps);
+        } else {
+            globals.staticSolver.step(numSteps);
+        }
+        setGeoUpdates();
+        globals.threeView.render();
+    }
+
+    function setGeoUpdates(){
+        geometry.attributes.position.needsUpdate = true;
+        if (globals.colorMode == "axialStrain") geometry.attributes.color.needsUpdate = true;
+        geometry.computeVertexNormals();
+    }
+
     var inited = false;
     startSolver();
 
@@ -138,9 +164,7 @@ function initModel(globals){
                 console.log("static");
             }
             geometry.attributes.position.needsUpdate = true;
-            if (globals.colorMode == "axialStrain") geometry.attributes.color.needsUpdate = true;
-            geometry.computeVertexNormals();
-            // geometry.computeFlatVertexNormals();
+            setGeoUpdates();
         });
     }
 
@@ -287,6 +311,8 @@ function initModel(globals){
     return {
         pause: pause,
         resume: resume,
+        reset: reset,
+        step: step,
         getNodes: getNodes,
         getEdges: getEdges,
         getFaces: getFaces,
diff --git a/js/pattern.js b/js/pattern.js
index ff74ac600c1cc0cb78a5c0cfc013353cfe21bc4c..67dd1185967597f35073dee6dbc5b05a477f6932 100644
--- a/js/pattern.js
+++ b/js/pattern.js
@@ -174,7 +174,6 @@ function initPattern(globals){
     }
 
     function getFacesAndVerticesForEdges(faces, allEdges){
-        //todo merge this
         var allCreaseParams = [];//face1Ind, vertInd, face2Ind, ver2Ind, edgeInd, angle
         for (var i=outlines.length;i<allEdges.length;i++){
             if (i>=outlines.length+mountains.length+valleys.length &&
diff --git a/js/threeView.js b/js/threeView.js
index d607b99c8a8b974fe67b756b46ae9c913e91e505..2ec807699a3c4d0d19b121f378ed6d1263f1b623 100644
--- a/js/threeView.js
+++ b/js/threeView.js
@@ -61,6 +61,7 @@ function initThreeView(globals) {
         controls.noPan = true;
         controls.staticMoving = true;
         controls.dynamicDampingFactor = 0.3;
+        controls.addEventListener("change", render);
 
         var renderPass = new THREE.RenderPass( scene, camera );
 
@@ -90,9 +91,9 @@ function initThreeView(globals) {
     }
 
     function render() {
-        // if (!animationRunning) {
-        //     _render();
-        // }
+        if (!animationRunning) {
+            _render();
+        }
     }
 
     function startAnimation(callback){
@@ -113,6 +114,10 @@ function initThreeView(globals) {
         if (animationRunning) pauseFlag = true;
     }
 
+    function running(){
+        return animationRunning;
+    }
+
     function _render(){
         if (globals.ambientOcclusion) {
             // Render depth into depthRenderTarget
@@ -186,6 +191,7 @@ function initThreeView(globals) {
         pauseAnimation: pauseAnimation,
         enableControls: enableControls,
         scene: scene,
-        camera: camera
+        camera: camera,
+        running: running
     }
 }
\ No newline at end of file