Improved undo / redo
This commit is contained in:
parent
c5f07757aa
commit
2e482079e1
|
@ -26,7 +26,14 @@ button.
|
||||||
|
|
||||||
<button class="btn btn-primary" id="full" style="margin-bottom: 10px; display: none;">Fullscreen</button>
|
<button class="btn btn-primary" id="full" style="margin-bottom: 10px; display: none;">Fullscreen</button>
|
||||||
<button class="btn btn-primary" id="reset" style="margin-bottom:10px">Reset camera</button>
|
<button class="btn btn-primary" id="reset" style="margin-bottom:10px">Reset camera</button>
|
||||||
<button class="btn btn-primary" id="undo" style="margin-bottom:10px">Undo</button>
|
|
||||||
|
<button class="btn btn-danger" id="undo" style="margin-bottom:10px">
|
||||||
|
<span class="glyphicon glyphicon-triangle-left" aria-hidden="true"></span>
|
||||||
|
</button>
|
||||||
|
|
||||||
|
<button class="btn btn-danger" id="redo" style="margin-bottom:10px">
|
||||||
|
<span class="glyphicon glyphicon-triangle-right" aria-hidden="true"></span>
|
||||||
|
</button>
|
||||||
<input type="checkbox" id="fullarrow" style="margin-bottom:10px">
|
<input type="checkbox" id="fullarrow" style="margin-bottom:10px">
|
||||||
<label for="fullarrow">Full arrow</label>
|
<label for="fullarrow">Full arrow</label>
|
||||||
<input type="checkbox" id="collisions" style="margin-bottom:10px" checked>
|
<input type="checkbox" id="collisions" style="margin-bottom:10px" checked>
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
---
|
---
|
||||||
title: Prototype
|
title: Prototype with old cameras
|
||||||
layout: withjs
|
layout: withjs
|
||||||
extrajs: <script src="/static/js/prototype/viewport/main.js"></script>
|
extrajs: <script src="/static/js/prototype/viewport/main.js"></script>
|
||||||
extrahead: <link rel="stylesheet" href="/static/css/prototype.css" />
|
extrahead: <link rel="stylesheet" href="/static/css/prototype.css" />
|
||||||
|
@ -26,7 +26,14 @@ button.
|
||||||
|
|
||||||
<button class="btn btn-primary" id="full" style="margin-bottom: 10px; display: none;">Fullscreen</button>
|
<button class="btn btn-primary" id="full" style="margin-bottom: 10px; display: none;">Fullscreen</button>
|
||||||
<button class="btn btn-primary" id="reset" style="margin-bottom:10px">Reset camera</button>
|
<button class="btn btn-primary" id="reset" style="margin-bottom:10px">Reset camera</button>
|
||||||
<button class="btn btn-primary" id="undo" style="margin-bottom:10px">Undo</button>
|
|
||||||
|
<button class="btn btn-danger" id="undo" style="margin-bottom:10px">
|
||||||
|
<span class="glyphicon glyphicon-triangle-left" aria-hidden="true"></span>
|
||||||
|
</button>
|
||||||
|
|
||||||
|
<button class="btn btn-danger" id="redo" style="margin-bottom:10px">
|
||||||
|
<span class="glyphicon glyphicon-triangle-right" aria-hidden="true"></span>
|
||||||
|
</button>
|
||||||
<input type="checkbox" id="fullarrow" style="margin-bottom:10px">
|
<input type="checkbox" id="fullarrow" style="margin-bottom:10px">
|
||||||
<label for="fullarrow">Full arrow</label>
|
<label for="fullarrow">Full arrow</label>
|
||||||
<input type="checkbox" id="collisions" style="margin-bottom:10px" checked>
|
<input type="checkbox" id="collisions" style="margin-bottom:10px" checked>
|
||||||
|
|
|
@ -37,6 +37,9 @@ var PointerCamera = function() {
|
||||||
// Raycaster for collisions
|
// Raycaster for collisions
|
||||||
this.raycaster = new THREE.Raycaster();
|
this.raycaster = new THREE.Raycaster();
|
||||||
|
|
||||||
|
// Create history object
|
||||||
|
this.history = new History();
|
||||||
|
|
||||||
// Set events from the document
|
// Set events from the document
|
||||||
var self = this;
|
var self = this;
|
||||||
var onKeyDown = function(event) {self.onKeyDown(event);};
|
var onKeyDown = function(event) {self.onKeyDown(event);};
|
||||||
|
@ -76,10 +79,10 @@ PointerCamera.prototype.update = function() {
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
// Update angles
|
// Update angles
|
||||||
if (this.increasePhi) this.phi += this.sensitivity;
|
if (this.increasePhi) {this.phi += this.sensitivity; this.changed = true; }
|
||||||
if (this.decreasePhi) this.phi -= this.sensitivity;
|
if (this.decreasePhi) {this.phi -= this.sensitivity; this.changed = true; }
|
||||||
if (this.increaseTheta) this.theta += this.sensitivity;
|
if (this.increaseTheta) {this.theta += this.sensitivity; this.changed = true; }
|
||||||
if (this.decreaseTheta) this.theta -= this.sensitivity;
|
if (this.decreaseTheta) {this.theta -= this.sensitivity; this.changed = true; }
|
||||||
|
|
||||||
if (this.dragging) {
|
if (this.dragging) {
|
||||||
this.theta += this.mouseMove.x;
|
this.theta += this.mouseMove.x;
|
||||||
|
@ -87,6 +90,8 @@ PointerCamera.prototype.update = function() {
|
||||||
|
|
||||||
this.mouseMove.x = 0;
|
this.mouseMove.x = 0;
|
||||||
this.mouseMove.y = 0;
|
this.mouseMove.y = 0;
|
||||||
|
|
||||||
|
this.changed = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Clamp phi and theta
|
// Clamp phi and theta
|
||||||
|
@ -110,10 +115,10 @@ PointerCamera.prototype.update = function() {
|
||||||
var direction = new THREE.Vector3();
|
var direction = new THREE.Vector3();
|
||||||
|
|
||||||
if (this.boost) speed *= 10;
|
if (this.boost) speed *= 10;
|
||||||
if (this.moveForward) direction.add(Tools.mul(forward, speed));
|
if (this.moveForward) {direction.add(Tools.mul(forward, speed)); this.changed = true;}
|
||||||
if (this.moveBackward) direction.sub(Tools.mul(forward, speed));
|
if (this.moveBackward) {direction.sub(Tools.mul(forward, speed)); this.changed = true;}
|
||||||
if (this.moveLeft) direction.add(Tools.mul(left, speed));
|
if (this.moveLeft) {direction.add(Tools.mul(left, speed)); this.changed = true;}
|
||||||
if (this.moveRight) direction.sub(Tools.mul(left, speed));
|
if (this.moveRight) {direction.sub(Tools.mul(left, speed)); this.changed = true;}
|
||||||
|
|
||||||
if (!this.collisions || !this.isColliding(direction)) {
|
if (!this.collisions || !this.isColliding(direction)) {
|
||||||
this.position.add(direction);
|
this.position.add(direction);
|
||||||
|
@ -129,6 +134,7 @@ PointerCamera.prototype.reset = function() {
|
||||||
this.position.copy(new THREE.Vector3(-8.849933489419644, 9.050627639459208, 0.6192960680432451));
|
this.position.copy(new THREE.Vector3(-8.849933489419644, 9.050627639459208, 0.6192960680432451));
|
||||||
this.target.copy(new THREE.Vector3(17.945323228767702, -15.156828589982375, -16.585740412769756));
|
this.target.copy(new THREE.Vector3(17.945323228767702, -15.156828589982375, -16.585740412769756));
|
||||||
this.anglesFromVectors();
|
this.anglesFromVectors();
|
||||||
|
this.save();
|
||||||
}
|
}
|
||||||
|
|
||||||
PointerCamera.prototype.vectorsFromAngles = function() {
|
PointerCamera.prototype.vectorsFromAngles = function() {
|
||||||
|
@ -154,7 +160,10 @@ PointerCamera.prototype.anglesFromVectors = function() {
|
||||||
this.theta = Math.atan2(forward.x, forward.z);
|
this.theta = Math.atan2(forward.x, forward.z);
|
||||||
}
|
}
|
||||||
|
|
||||||
PointerCamera.prototype.move = function(otherCamera) {
|
PointerCamera.prototype.move = function(otherCamera, toSave) {
|
||||||
|
if (toSave === undefined)
|
||||||
|
toSave = true;
|
||||||
|
|
||||||
this.moving = true;
|
this.moving = true;
|
||||||
this.new_target = otherCamera.target.clone();
|
this.new_target = otherCamera.target.clone();
|
||||||
this.new_position = otherCamera.position.clone();
|
this.new_position = otherCamera.position.clone();
|
||||||
|
@ -163,6 +172,14 @@ PointerCamera.prototype.move = function(otherCamera) {
|
||||||
var fp = [Tools.diff(this.target, this.position), Tools.diff(this.new_target, this.new_position)];
|
var fp = [Tools.diff(this.target, this.position), Tools.diff(this.new_target, this.new_position)];
|
||||||
this.hermite = new Hermite.Polynom(t,f,fp);
|
this.hermite = new Hermite.Polynom(t,f,fp);
|
||||||
this.t = 0;
|
this.t = 0;
|
||||||
|
|
||||||
|
if (toSave) {
|
||||||
|
if (this.changed) {
|
||||||
|
this.save();
|
||||||
|
this.changed = false;
|
||||||
|
}
|
||||||
|
this.history.addState({position: otherCamera.position.clone(), target: otherCamera.target.clone()});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
PointerCamera.prototype.isColliding = function(direction) {
|
PointerCamera.prototype.isColliding = function(direction) {
|
||||||
|
@ -248,15 +265,74 @@ PointerCamera.prototype.log = function() {
|
||||||
}
|
}
|
||||||
|
|
||||||
PointerCamera.prototype.save = function() {
|
PointerCamera.prototype.save = function() {
|
||||||
this.backup = {};
|
var backup = {};
|
||||||
this.backup.position = this.position.clone();
|
backup.position = this.position.clone();
|
||||||
this.backup.target = this.target.clone();
|
backup.target = this.target.clone();
|
||||||
|
this.history.addState(backup);
|
||||||
}
|
}
|
||||||
|
|
||||||
PointerCamera.prototype.load = function() {
|
PointerCamera.prototype.undo = function() {
|
||||||
this.move(this.backup);
|
var move = this.history.undo();
|
||||||
|
if (move !== undefined)
|
||||||
|
this.move(move, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
PointerCamera.prototype.redo = function() {
|
||||||
|
var move = this.history.redo();
|
||||||
|
if (move !== undefined)
|
||||||
|
this.move(move, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
PointerCamera.prototype.undoable = function() {
|
||||||
|
return this.history.undoable();
|
||||||
|
}
|
||||||
|
|
||||||
|
PointerCamera.prototype.redoable = function() {
|
||||||
|
return this.history.redoable();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Static members
|
// Static members
|
||||||
PointerCamera.DISTANCE_X = 1000;
|
PointerCamera.DISTANCE_X = 1000;
|
||||||
PointerCamera.DISTANCE_Z = 300;
|
PointerCamera.DISTANCE_Z = 300;
|
||||||
|
|
||||||
|
var History = function() {
|
||||||
|
this.states = new Array();
|
||||||
|
this.index = -1;
|
||||||
|
this.size = 0;
|
||||||
|
console.log('New state ' + this.index + ' / ' + this.size);
|
||||||
|
}
|
||||||
|
|
||||||
|
History.prototype.addState = function(state) {
|
||||||
|
++this.index;
|
||||||
|
this.size = this.index + 1;
|
||||||
|
this.states[this.size-1] = state;
|
||||||
|
console.log('New state ' + this.index + ' / ' + this.size);
|
||||||
|
}
|
||||||
|
|
||||||
|
History.prototype.undo = function() {
|
||||||
|
if (this.undoable()) {
|
||||||
|
this.index--;
|
||||||
|
console.log('New state ' + this.index + ' / ' + this.size);
|
||||||
|
return this.currentState();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
History.prototype.redo = function() {
|
||||||
|
if (this.redoable()) {
|
||||||
|
this.index++;
|
||||||
|
console.log('New state ' + this.index + ' / ' + this.size);
|
||||||
|
return this.currentState();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
History.prototype.undoable = function() {
|
||||||
|
return this.index > 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
History.prototype.redoable = function() {
|
||||||
|
return this.index < this.size - 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
History.prototype.currentState = function() {
|
||||||
|
return this.states[this.index];
|
||||||
|
}
|
||||||
|
|
|
@ -35,6 +35,24 @@ var prev = {x:0, y:0, go:false};
|
||||||
var showArrows = true;
|
var showArrows = true;
|
||||||
var beenFullscreen = false;
|
var beenFullscreen = false;
|
||||||
|
|
||||||
|
var undoElement = document.getElementById('undo');
|
||||||
|
var redoElement = document.getElementById('redo');
|
||||||
|
|
||||||
|
function updateElements() {
|
||||||
|
// Update icon
|
||||||
|
if (!cameras.mainCamera().undoable()) {
|
||||||
|
undoElement.className = "btn btn-danger";
|
||||||
|
} else {
|
||||||
|
undoElement.className = "btn btn-primary";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!cameras.mainCamera().redoable()) {
|
||||||
|
redoElement.className = "btn btn-danger";
|
||||||
|
} else {
|
||||||
|
redoElement.className = "btn btn-primary";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
init();
|
init();
|
||||||
animate();
|
animate();
|
||||||
|
|
||||||
|
@ -65,8 +83,15 @@ function init() {
|
||||||
showArrows = showarrows.checked;
|
showArrows = showarrows.checked;
|
||||||
}
|
}
|
||||||
|
|
||||||
document.getElementById('undo').onclick = function() {
|
undoElement.onclick = function() {
|
||||||
cameras.mainCamera().load();
|
cameras.mainCamera().undo();
|
||||||
|
updateElements();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
redoElement.onclick = function() {
|
||||||
|
cameras.mainCamera().redo();
|
||||||
|
updateElements();
|
||||||
}
|
}
|
||||||
|
|
||||||
// on initialise le moteur de rendu
|
// on initialise le moteur de rendu
|
||||||
|
@ -479,8 +504,8 @@ function updateMouse(event) {
|
||||||
function click(event) {
|
function click(event) {
|
||||||
var newCamera = pointedCamera(event);
|
var newCamera = pointedCamera(event);
|
||||||
if (newCamera !== undefined) {
|
if (newCamera !== undefined) {
|
||||||
cameras.mainCamera().save();
|
|
||||||
cameras.mainCamera().move(newCamera);
|
cameras.mainCamera().move(newCamera);
|
||||||
|
updateElements();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -35,6 +35,24 @@ var prev = {x:0, y:0, go:false};
|
||||||
var showArrows = true;
|
var showArrows = true;
|
||||||
var beenFullscreen = false;
|
var beenFullscreen = false;
|
||||||
|
|
||||||
|
var undoElement = document.getElementById('undo');
|
||||||
|
var redoElement = document.getElementById('redo');
|
||||||
|
|
||||||
|
function updateElements() {
|
||||||
|
// Update icon
|
||||||
|
if (!cameras.mainCamera().undoable()) {
|
||||||
|
undoElement.className = "btn btn-danger";
|
||||||
|
} else {
|
||||||
|
undoElement.className = "btn btn-primary";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!cameras.mainCamera().redoable()) {
|
||||||
|
redoElement.className = "btn btn-danger";
|
||||||
|
} else {
|
||||||
|
redoElement.className = "btn btn-primary";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
init();
|
init();
|
||||||
animate();
|
animate();
|
||||||
|
|
||||||
|
@ -65,8 +83,15 @@ function init() {
|
||||||
showArrows = showarrows.checked;
|
showArrows = showarrows.checked;
|
||||||
}
|
}
|
||||||
|
|
||||||
document.getElementById('undo').onclick = function() {
|
undoElement.onclick = function() {
|
||||||
cameras.mainCamera().load();
|
cameras.mainCamera().undo();
|
||||||
|
updateElements();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
redoElement.onclick = function() {
|
||||||
|
cameras.mainCamera().redo();
|
||||||
|
updateElements();
|
||||||
}
|
}
|
||||||
|
|
||||||
// on initialise le moteur de rendu
|
// on initialise le moteur de rendu
|
||||||
|
@ -479,8 +504,8 @@ function updateMouse(event) {
|
||||||
function click(event) {
|
function click(event) {
|
||||||
var newCamera = pointedCamera(event);
|
var newCamera = pointedCamera(event);
|
||||||
if (newCamera !== undefined) {
|
if (newCamera !== undefined) {
|
||||||
cameras.mainCamera().save();
|
|
||||||
cameras.mainCamera().move(newCamera);
|
cameras.mainCamera().move(newCamera);
|
||||||
|
updateElements();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue