Skip to content

Commit 83e20a1

Browse files
committed
Merge branch 'hotfix-5.1.3'
2 parents 5339216 + 483aa9c commit 83e20a1

File tree

10 files changed

+120
-32
lines changed

10 files changed

+120
-32
lines changed

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ xml3d.js is a [XML3D](http://www.xml3d.org) implementation based on WebGL and Ja
99
as developing web pages. Every web developer who knows how to use the DOM (or jQuery) should also be able to use XML3D.
1010

1111
XML3D is also an evaluation platform of the W3C Community Group [Declarative 3D for the Web](http://www.w3.org/community/declarative3d/) and
12-
a [FI-WARE Generic Enabler](http://catalogue.fiware.org/enablers/3d-ui-xml3d).
12+
a [FIWARE Generic Enabler](http://catalogue.fiware.org/enablers/3d-ui-xml3d).
1313

1414
#### Examples ####
1515
Here you can find [small examples](https://github.com/xml3d/xml3d-examples) of individual features. Below are some more complete demos:

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
"name": "xml3d.js",
33
"description": "XML3D implementation based on JS and WebGL",
44
"homepage": "http://ww.xml3d.org",
5-
"version": "5.1.2",
5+
"version": "5.1.3",
66
"repository": {
77
"type": "git",
88
"url": "https://github.com/xml3d/xml3d.js"

spec/index.html

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -3219,8 +3219,8 @@ <h3>Vec2</h3>
32193219
<dd>Creates a new Vec2 object from the space-separated string representation as used in XML3D element
32203220
attributes.
32213221
</dd>
3222-
<dt>DOMString toDOMString(Vec2 vec)</dt>
3223-
<dd>Converts a Vec2 into the space-seperated string representation used in XML3D element attributes.</dd>
3222+
<dt>DOMString toDOMString()</dt>
3223+
<dd>Returns a space-seperated string representation for use in XML3D element attributes or value elements.</dd>
32243224

32253225
<dt>Constructor ()</dt>
32263226
<dd>Creates a new identity Vec2 <code>[0,0]</code></dd>
@@ -3304,8 +3304,8 @@ <h3>Vec3</h3>
33043304
<dd>Creates a new Vec3 object from the space-separated string representation as used in XML3D element
33053305
attributes.
33063306
</dd>
3307-
<dt>DOMString toDOMString(Vec3 vec)</dt>
3308-
<dd>Converts a Vec3 into the space-seperated string representation used in XML3D element attributes.</dd>
3307+
<dt>DOMString toDOMString()</dt>
3308+
<dd>Returns a space-seperated string representation for use in XML3D element attributes or value elements.</dd>
33093309

33103310
<dt>Constructor ()</dt>
33113311
<dd>Creates a new identity Vec3 <code>[0,0,0]</code></dd>
@@ -3399,8 +3399,8 @@ <h3>Vec4</h3>
33993399
<dd>Creates a new Vec4 object from the space-separated string representation as used in XML3D element
34003400
attributes.
34013401
</dd>
3402-
<dt>DOMString toDOMString(Vec4 vec)</dt>
3403-
<dd>Converts a Vec4 into the space-seperated string representation used in XML3D element attributes.</dd>
3402+
<dt>DOMString toDOMString()</dt>
3403+
<dd>Returns a space-seperated string representation for use in XML3D element attributes or value elements.</dd>
34043404

34053405
<dt>Constructor ()</dt>
34063406
<dd>Creates a new identity Vec4 <code>[0,0,0,0]</code></dd>
@@ -3480,8 +3480,8 @@ <h3>AxisAngle</h3>
34803480
<dd>Creates a new AxisAngle object from the space-separated string representation as used in XML3D element
34813481
attributes.
34823482
</dd>
3483-
<dt>DOMString toDOMString(AxisAngle vec)</dt>
3484-
<dd>Converts a AxisAngle into the space-seperated string representation used in XML3D element attributes.
3483+
<dt>DOMString toDOMString()</dt>
3484+
<dd>Returns a space-seperated string representation for use in XML3D element attributes or value elements.
34853485
</dd>
34863486

34873487
<dt>Constructor ()</dt>
@@ -3526,8 +3526,8 @@ <h3>Quat</h3>
35263526
<dd>Provides mutable access to the fourth component of this quaternion.</dd>
35273527
<dt>static Quat fromDOMString(DOMString str)</dt>
35283528
<dd>Creates a new Quat object from a space-separated string representation.</dd>
3529-
<dt>DOMString toDOMString(Quat vec)</dt>
3530-
<dd>Converts a Quat into a space-seperated string representation.</dd>
3529+
<dt>DOMString toDOMString()</dt>
3530+
<dd>Returns a space-seperated string representation for use in XML3D element attributes or value elements.</dd>
35313531

35323532
<dt>Constructor ()</dt>
35333533
<dd>Creates a new identity Quat <code>[0,0,0,1]</code></dd>
@@ -3891,6 +3891,8 @@ <h3>Box</h3>
38913891
<dd>Returns true if the given point is inside the box.</dd>
38923892
<dt>DOMString toString()</dt>
38933893
<dd>A human readable string representation of this box.</dd>
3894+
<dt>DOMString toDOMString()</dt>
3895+
<dd>Returns a space-seperated string representation for use in XML3D element attributes or value elements.</dd>
38943896
</dl>
38953897
</section>
38963898
<section>

src/renderer/renderer/adapter/light.js

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ XML3D.createClass(LightRenderAdapter, SceneElementAdapter, {
2727
parent: parentNode
2828
});
2929
this.updateVisibility();
30+
this.updateLocalMatrix();
3031
},
3132

3233
attributeChangedCallback: function (name, oldValue, newValue) {
@@ -79,6 +80,15 @@ XML3D.createClass(LightRenderAdapter, SceneElementAdapter, {
7980
var m = new XML3D.Mat4();
8081
this.renderNode.getWorldMatrix(m.data);
8182
return m;
83+
},
84+
85+
/**
86+
* @return {XML3D.Mat4}
87+
*/
88+
getLocalMatrix: function () {
89+
var m = new XML3D.Mat4();
90+
this.renderNode.getLocalMatrix(m.data);
91+
return m;
8292
}
8393
});
8494

src/renderer/renderer/scene/renderlight.js

Lines changed: 25 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -7,13 +7,12 @@ var EVENT_TYPE = Constants.EVENT_TYPE;
77

88
var tmp_worldMatrix = XML3D.math.mat4.create();
99

10-
var SHADOWMAP_OFFSET_MATRIX = new Float32Array([0.5, 0.0, 0.0, 0.0, 0.0, 0.5, 0.0, 0.0, 0.0, 0.0, 0.5, 0.0, 0.5, 0.5, 0.5, 1.0]);
11-
1210
/** @const */
13-
var CLIPPLANE_NEAR_MIN = 1.0;
14-
11+
var WORLD_MATRIX_OFFSET = 0;
12+
/** @const */
13+
var LOCAL_MATRIX_OFFSET = WORLD_MATRIX_OFFSET + 16;
1514
/** @const */
16-
var ENTRY_SIZE = 16;
15+
var ENTRY_SIZE = LOCAL_MATRIX_OFFSET;
1716

1817
var c_BoundingBox = new XML3D.Box();
1918

@@ -63,10 +62,20 @@ XML3D.extend(RenderLight.prototype, {
6362
this.lightStructureChanged(false);
6463
},
6564

66-
setLocalMatrix: function (source) {
67-
XML3D.debug.logError("RenderLight::setLocalMatrix not implemented");
65+
getLocalMatrix: function (dest) {
66+
var o = this.offset + LOCAL_MATRIX_OFFSET;
67+
for (var i = 0; i < 16; i++, o++) {
68+
dest[i] = this.page[o];
69+
}
6870
},
6971

72+
setLocalMatrix: function (source) {
73+
var o = this.offset + LOCAL_MATRIX_OFFSET;
74+
for (var i = 0; i < 16; i++, o++) {
75+
this.page[o] = source[i];
76+
}
77+
this.setTransformDirty();
78+
},
7079

7180
getFrustum: function (aspect) {
7281
this.scene.getBoundingBox(c_BoundingBox);
@@ -83,13 +92,13 @@ XML3D.extend(RenderLight.prototype, {
8392
this.scene.emit(EVENT_TYPE.LIGHT_STRUCTURE_CHANGED, this, removed);
8493
},
8594

86-
updateWorldMatrix: function () {
87-
if (this.parent) {
88-
this.parent.getWorldMatrix(tmp_worldMatrix);
89-
this.setWorldMatrix(tmp_worldMatrix);
90-
// We change position / direction of the light
91-
this.lightValueChanged();
92-
}
95+
updateWorldMatrix: function (sourceMat4) {
96+
var page = this.page;
97+
var offset = this.offset;
98+
XML3D.math.mat4.multiplyOffset(page, offset + WORLD_MATRIX_OFFSET, page, offset + LOCAL_MATRIX_OFFSET, sourceMat4, 0);
99+
// We change position / direction of the light
100+
this.lightValueChanged();
101+
this.transformDirty = false;
93102
},
94103

95104
visibilityChanged: function (newVal) {
@@ -98,17 +107,16 @@ XML3D.extend(RenderLight.prototype, {
98107
},
99108

100109
setTransformDirty: function () {
101-
this.updateWorldMatrix();
110+
this.parent.getWorldMatrix(tmp_worldMatrix);
111+
this.updateWorldMatrix(tmp_worldMatrix);
102112
},
103113

104-
105114
remove: function () {
106115
this.parent.removeChild(this);
107116
this.scene.lights.remove(this);
108117
this.lightStructureChanged(true);
109118
},
110119

111-
112120
getWorldSpaceBoundingBox: function (bbox) {
113121
bbox.setEmpty();
114122
}

src/resource/coordinator.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -222,16 +222,17 @@ function invalidateHandles(uri) {
222222
* @param {URI} uri The URI of the document
223223
*/
224224
function invalidateDocumentHandles(uri) {
225+
invalidateHandles(uri);
225226
var url = uri.toStringWithoutFragment();
226227
var docCache = getDocumentCache(url);
227228
if (!docCache) {
228229
// The document was never loaded
229-
invalidateHandles(uri);
230230
return;
231231
}
232232
var fragments = docCache.fragments;
233233
docCache.fragments = [];
234234
for (var i = 0; i < fragments.length; ++i) {
235+
uri.fragment = fragments[i];
235236
invalidateHandles(uri);
236237
}
237238
}

src/resource/fetcher.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@ Resource.getDocument = function(urlString, opt) {
7070
if (opt.allowCaching) {
7171
if (cache = c_cachedDocuments.get(urlString)) {
7272
// We can skip the fetch phase and piggy back on the result of the previous fetch, this avoids unnecessary Requests
73-
return cache.pending ? cache.pending : Promise.resolve(cache.document);
73+
return cache.pending ? Promise.race([cache.pending]) : Promise.resolve(cache.document);
7474
}
7575

7676
// There is no pending or complete Request for this url so lets create a cache entry and start one

src/types/box.js

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -199,6 +199,11 @@ Box.prototype.toString = function() {
199199
this.data[4] + ', ' + this.data[5] + ')';
200200
};
201201

202+
Box.prototype.toDOMString = function() {
203+
return this.data[0] + ' ' + this.data[1] + ' ' + this.data[2] + ' ' + this.data[3] + ' ' +
204+
this.data[4] + ' ' + this.data[5];
205+
};
206+
202207
Box.EMPTY_BOX = new Box();
203208

204209
module.exports = Box;

tests/lights.js

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -279,6 +279,64 @@ test("Change light shader", 4, function() {
279279

280280
});
281281

282+
test("Change light transformation", function() {
283+
stop();
284+
var frameLoaded = Q.fcall(promiseIFrameLoaded, "scenes/webgl-rendering03.html");
285+
286+
var test = frameLoaded.then(function (doc) {
287+
var s = doc.querySelector("#xml3DElem");
288+
doc.getElementById("pointlight").style.display = 'inherit';
289+
doc.getElementById("dirlight").style.display = 'none';
290+
doc.getElementById("phongShadedGroup").style.display = 'inherit';
291+
292+
return s;
293+
}).then(promiseSceneRendered).then(function (s) {
294+
var actual = XML3DUnit.getPixelValue(getContextForXml3DElement(s), 90, 90);
295+
deepEqual(actual, [255,0,0,255], "Phong object is lit by red point light shader");
296+
297+
var light = s.ownerDocument.querySelector("#pointlightLight");
298+
QUnit.closeMatrix(light.getLocalMatrix(), new XML3D.Mat4(), EPSILON, "Light has a local transform matrix that is identity");
299+
300+
light.setAttribute("style", "transform: translate3d(0, 0, -10px)");
301+
302+
return s;
303+
}).then(promiseSceneRendered).then(function (s) {
304+
var light = s.ownerDocument.querySelector("#pointlightLight");
305+
QUnit.closeMatrix(light.getLocalMatrix(), new XML3D.Mat4().translate(new XML3D.Vec3(0,0,-10)), EPSILON, "Light's local matrix was updated with new style transform");
306+
var parentWorld = light.parentElement.getWorldMatrix();
307+
QUnit.closeMatrix(light.getWorldMatrix(), parentWorld.translate(new XML3D.Vec3(0,0,-10)), EPSILON, "Light's world matrix matches parent * local");
308+
309+
var actual = XML3DUnit.getPixelValue(getContextForXml3DElement(s), 90, 90);
310+
deepEqual(actual, [0,0,0,255], "Light is properly positioned behind the square");
311+
312+
light.removeAttribute("style");
313+
314+
return s;
315+
}).then(promiseSceneRendered).then(function(s) {
316+
var actual = XML3DUnit.getPixelValue(getContextForXml3DElement(s), 90, 90);
317+
deepEqual(actual, [255,0,0,255], "Light position was reset once local transform was removed");
318+
319+
var transform = s.ownerDocument.createElement("transform");
320+
transform.setAttribute("id", "test_light_transform");
321+
transform.setAttribute("translation", "0 0 -10");
322+
s.appendChild(transform);
323+
324+
s.ownerDocument.querySelector("#pointlightLight").setAttribute("transform", "#test_light_transform");
325+
return s;
326+
}).then(promiseSceneRendered).then(function(s) {
327+
var light = s.ownerDocument.querySelector("#pointlightLight");
328+
QUnit.closeMatrix(light.getLocalMatrix(), new XML3D.Mat4().translate(new XML3D.Vec3(0,0,-10)), EPSILON, "Light's local matrix was updated with new transform element");
329+
var parentWorld = light.parentElement.getWorldMatrix();
330+
QUnit.closeMatrix(light.getWorldMatrix(), parentWorld.translate(new XML3D.Vec3(0,0,-10)), EPSILON, "Light's world matrix matches parent * local");
331+
332+
var actual = XML3DUnit.getPixelValue(getContextForXml3DElement(s), 90, 90);
333+
deepEqual(actual, [0,0,0,255], "Light is properly positioned behind the square");
334+
});
335+
336+
test.fin(QUnit.start).done();
337+
338+
});
339+
282340

283341
module("Lights", {
284342
setup : function() {

tools/camera.js

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -115,8 +115,12 @@
115115
return;
116116
}
117117
var bb = element.getWorldBoundingBox();
118+
if (bb.isEmpty()) {
119+
XML3D.debug.logError("The given element has an empty bounding box, ensure it has finished loading before trying to examine it!", element);
120+
return;
121+
}
118122
var center = bb.center();
119-
var r = center.len();
123+
var r = center.sub(bb.min).len();
120124
var newPos = center.clone();
121125
newPos.z += r / Math.tan(this.transformInterface.fieldOfView / 2);
122126
this.transformInterface.position = newPos;

0 commit comments

Comments
 (0)