summaryrefslogtreecommitdiffstats
path: root/o3d/samples/o3d-webgl/client.js
diff options
context:
space:
mode:
Diffstat (limited to 'o3d/samples/o3d-webgl/client.js')
-rw-r--r--o3d/samples/o3d-webgl/client.js161
1 files changed, 105 insertions, 56 deletions
diff --git a/o3d/samples/o3d-webgl/client.js b/o3d/samples/o3d-webgl/client.js
index 869320b..877bee4 100644
--- a/o3d/samples/o3d-webgl/client.js
+++ b/o3d/samples/o3d-webgl/client.js
@@ -225,6 +225,20 @@ o3d.Client = function() {
o3d.Renderer.installRenderInterval();
o3d.Renderer.clients_.push(this);
+
+ /**
+ * Stack of objects showing how the state has changed.
+ * @type {!Array.<!Object>}
+ * @private
+ */
+ this.stateMapStack_ = [];
+
+ /**
+ * An object containing an entry for each state variable that has changed.
+ * @type {Object}
+ * @private
+ */
+ this.stateVariableStacks_ = {};
};
o3d.inherit('Client', 'NamedObject');
@@ -426,6 +440,8 @@ o3d.Client.prototype.render = function() {
// Synthesize a render event.
var render_event = new o3d.RenderEvent;
+ this.clearStateStack_();
+
var now = (new Date()).getTime() * 0.001;
if(this.then_ == 0.0)
render_event.elapsedTime = 0.0;
@@ -611,7 +627,9 @@ o3d.Client.prototype.initWithCanvas = function(canvas) {
if (!canvas || !canvas.getContext) {
return false;
}
- try {gl = canvas.getContext("experimental-webgl", standard_attributes) } catch(e) { }
+ try {
+ gl = canvas.getContext("experimental-webgl", standard_attributes)
+ } catch(e) { }
if (!gl) {
try {
gl = canvas.getContext("moz-webgl")
@@ -632,6 +650,7 @@ o3d.Client.prototype.initWithCanvas = function(canvas) {
gl.client = this;
gl.displayInfo = {width: canvas.width,
height: canvas.height};
+ o3d.State.createDefaultState_(gl).push_();
return true;
};
@@ -762,78 +781,34 @@ o3d.Client.getEventInfo_ = function(event) {
/**
- * Returns the absolute position of an element for certain browsers.
+ * Returns the absolute position of an element.
* @param {!HTMLElement} element The element to get a position for.
* @return {!Object} An object containing x and y as the absolute position
* of the given element.
* @private
*/
o3d.Client.getAbsolutePosition_ = function(element) {
- var r = { x: element.offsetLeft, y: element.offsetTop };
- if (element.offsetParent) {
- var tmp = o3d.Client.getAbsolutePosition_(element.offsetParent);
- r.x += tmp.x;
- r.y += tmp.y;
+ var r = {x: 0, y: 0};
+ for (var e = element; e; e = e.offsetParent) {
+ r.x += e.offsetLeft;
+ r.y += e.offsetTop;
}
return r;
};
/**
- * Retrieve the coordinates of the given event relative to the center
- * of the widget.
+ * Compute the x and y of an event with respect to the element which received
+ * the event.
*
* @param {!Object} eventInfo As returned from
* o3d.Client.getEventInfo.
- * @param {HTMLElement} opt_reference A DOM element whose position we want
- * to transform the mouse coordinates to. If it is not passed in the
- * element in the eventInfo will be used.
* @return {!Object} An object containing keys 'x' and 'y'.
* @private
*/
-o3d.Client.getRelativeCoordinates_ = function(eventInfo, opt_reference) {
- var x, y;
+o3d.Client.getLocalXY_ = function(eventInfo) {
var event = eventInfo.event;
- var element = eventInfo.element;
- var reference = opt_reference || eventInfo.element;
- if (!window.opera && typeof event.offsetX != 'undefined') {
- // Use offset coordinates and find common offsetParent
- var pos = { x: event.offsetX, y: event.offsetY };
- // Send the coordinates upwards through the offsetParent chain.
- var e = element;
- while (e) {
- e.mouseX_ = pos.x;
- e.mouseY_ = pos.y;
- pos.x += e.offsetLeft;
- pos.y += e.offsetTop;
- e = e.offsetParent;
- }
- // Look for the coordinates starting from the reference element.
- var e = reference;
- var offset = { x: 0, y: 0 }
- while (e) {
- if (typeof e.mouseX_ != 'undefined') {
- x = e.mouseX_ - offset.x;
- y = e.mouseY_ - offset.y;
- break;
- }
- offset.x += e.offsetLeft;
- offset.y += e.offsetTop;
- e = e.offsetParent;
- }
- // Reset stored coordinates
- e = element;
- while (e) {
- e.mouseX_ = undefined;
- e.mouseY_ = undefined;
- e = e.offsetParent;
- }
- } else {
- // Use absolute coordinates
- var pos = o3d.Client.getAbsolutePosition_(reference);
- x = event.pageX - pos.x;
- y = event.pageY - pos.y;
- }
- return { x: x, y: y };
+ var p = o3d.Client.getAbsolutePosition_(eventInfo.element);
+ return {x: event.x - p.x, y: event.y - p.y};
};
@@ -849,7 +824,9 @@ o3d.Client.wrapEventCallback_ = function(handler, doCancelEvent) {
return function(event) {
event = o3d.Client.getEvent_(event);
var info = o3d.Client.getEventInfo_(event);
- var relativeCoords = o3d.Client.getRelativeCoordinates_(info);
+ var relativeCoords = o3d.Client.getLocalXY_(info);
+ // In a proper event, there are read only properties, so we clone it.
+ event = o3d.clone(event);
event.x = relativeCoords.x;
event.y = relativeCoords.y;
// Invert value to meet contract for deltaY. @see event.js.
@@ -1041,6 +1018,78 @@ o3d.Client.prototype.toDataURL =
/**
+ * Saves data needed to return state to current, then sets the state according
+ * to the given object.
+ * @private
+ */
+o3d.Client.prototype.clearStateStack_ = function() {
+ this.stateMapStack_ = [];
+ for (var name in this.stateVariableStacks_) {
+ var l = this.stateVariableStacks_[name];
+ // Recall there is a default value at the bottom of each of these stacks.
+ if (l.length != 1) {
+ this.stateVariableStacks_[name] = l.slice(0, 1);
+ }
+ }
+};
+
+
+/**
+ * Saves data needed to return state to current, then sets the state according
+ * to the given object.
+ * @param {Object} variable_map A map linking names to values.
+ * @private
+ */
+o3d.Client.prototype.pushState_ = function(variable_map) {
+ // Save the variable map itself in a stack.
+ this.stateMapStack_.push(variable_map);
+
+ // Save each of the state's variable's value in its own stack.
+ for (var name in variable_map) {
+ var value = variable_map[name];
+ if (this.stateVariableStacks_[name] == undefined) {
+ this.stateVariableStacks_[name] = [];
+ }
+ this.stateVariableStacks_[name].push(value);
+ }
+
+ // The value on the top of the stack in stateVariableStacks_
+ // is current at this point.
+ o3d.State.setVariables_(this.gl, variable_map);
+};
+
+
+/**
+ * Returns the state to the way it was before the current state
+ * @private
+ */
+o3d.Client.prototype.popState_ = function() {
+ var variable_map = this.stateMapStack_.pop();
+
+ for (var name in variable_map) {
+ var stack = this.stateVariableStacks_[name];
+ stack.pop();
+ variable_map[name] = stack.length ? stack[stack.length - 1] :
+ o3d.State.stateVariableInfos_[name]['defaultValue'];
+ }
+
+ o3d.State.setVariables_(this.gl, variable_map);
+};
+
+
+/**
+ * Gets the current value of the state variable with the give name.
+ * @param {string} name The name of the state variable in question.
+ * @private
+ */
+o3d.Client.prototype.getState_ = function(name) {
+ var stack = this.stateVariableStacks_[name];
+ return stack.length ? stack[stack.length - 1] :
+ o3d.State.stateVariableInfos_[name]['defaultValue'];
+};
+
+
+/**
* Returns the status of initializing the renderer so we can display the
* appropriate message. We require a certain minimum set of graphics
* capabilities. If the user's computer does not have his minimum