Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Cubemap update #2239

Merged
merged 6 commits into from Jul 3, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
56 changes: 24 additions & 32 deletions src/asset/asset-registry.js
Expand Up @@ -343,7 +343,6 @@ Object.assign(AssetRegistry.prototype, {

var self = this;
var file = asset.getPreferredFile();
var load = !!file;

// open has completed on the resource
var _opened = function (resource) {
Expand All @@ -353,6 +352,7 @@ Object.assign(AssetRegistry.prototype, {
asset.resource = resource;
}

// let handler patch the resource
self._loader.patch(asset, self);

self.fire("load", asset);
Expand All @@ -362,49 +362,41 @@ Object.assign(AssetRegistry.prototype, {
asset.fire("load", asset);
};

var _load = function () {
var url = asset.getFileUrl();

asset.loading = true;

self._loader.load(url, asset.type, function (err, resource, extra) {
asset.loaded = true;
asset.loading = false;

if (err) {
self.fire("error", err, asset);
self.fire("error:" + asset.id, err, asset);
asset.fire("error", err, asset);
return;
}
// load has completed on the resource
var _loaded = function (err, resource, extra) {
asset.loaded = true;
asset.loading = false;

if (err) {
self.fire("error", err, asset);
self.fire("error:" + asset.id, err, asset);
asset.fire("error", err, asset);
} else {
if (!script.legacy && asset.type === 'script') {
var loader = self._loader.getHandler('script');

if (loader._cache[asset.id] && loader._cache[asset.id].parentNode === document.head) {
var handler = self._loader.getHandler('script');
if (handler._cache[asset.id] && handler._cache[asset.id].parentNode === document.head) {
// remove old element
document.head.removeChild(loader._cache[asset.id]);
document.head.removeChild(handler._cache[asset.id]);
}

loader._cache[asset.id] = extra;
handler._cache[asset.id] = extra;
}

_opened(resource);
}, asset);
}
};

var _open = function () {
if (file || asset.type === 'cubemap') {
// start loading the resource
this.fire("load:start", asset);
this.fire("load:" + asset.id + ":start", asset);

asset.loading = true;
self._loader.load(asset.getFileUrl(), asset.type, _loaded, asset);
} else {
// asset has no file to load, open it directly
var resource = self._loader.open(asset.type, asset.data);
asset.loaded = true;
_opened(resource);
};

if (!file) {
_open();
} else if (load) {
this.fire("load:start", asset);
this.fire("load:" + asset.id + ":start", asset);
_load();
}
},

Expand Down
28 changes: 15 additions & 13 deletions src/resources/cubemap.js
Expand Up @@ -35,14 +35,13 @@ Object.assign(CubemapHandler.prototype, {
patch: function (asset, registry) {
this.loadAssets(asset, function (err, result) {
if (err) {
// fire error event if patch failed
registry.fire('error', asset);
registry.fire('error:' + asset.id, err, asset);
asset.fire('error', asset);
} else {
registry.fire('load', asset);
registry.fire('load:' + asset.id, asset);
asset.fire('load', asset);
}
// nothing to do since asset:change would have been raised if
// resources were changed.
});
},

Expand Down Expand Up @@ -174,15 +173,18 @@ Object.assign(CubemapHandler.prototype, {
resources[0] = oldResources[0] || null;
}

// set the new resources, change events will fire
cubemapAsset.resources = resources;
cubemapAsset._handlerState.assetIds = assetIds;
cubemapAsset._handlerState.assets = assets;

// destroy the old cubemap resources that are not longer needed
for (i = 0; i < oldResources.length; ++i) {
if (oldResources[i] !== null && resources.indexOf(oldResources[i]) === -1) {
oldResources[i].destroy();
// check if any resource changed
if (!this.cmpArrays(resources, oldResources)) {
// set the new resources, change events will fire
cubemapAsset.resources = resources;
cubemapAsset._handlerState.assetIds = assetIds;
cubemapAsset._handlerState.assets = assets;

// destroy the old cubemap resources that are not longer needed
for (i = 0; i < oldResources.length; ++i) {
if (oldResources[i] !== null && resources.indexOf(oldResources[i]) === -1) {
oldResources[i].destroy();
}
}
}

Expand Down
22 changes: 22 additions & 0 deletions src/resources/loader.js
Expand Up @@ -90,6 +90,12 @@ Object.assign(ResourceLoader.prototype, {
return;
}

// handle requests with null file
if (!url) {
this._loadNull(handler, callback, asset);
return;
}

var key = url + type;

if (this._cache[key] !== undefined) {
Expand Down Expand Up @@ -152,6 +158,22 @@ Object.assign(ResourceLoader.prototype, {
}
},

// load an asset with no url, skipping bundles and caching
_loadNull: function (handler, callback, asset) {
var onLoad = function (err, data, extra) {
if (err) {
callback(err);
} else {
try {
callback(null, handler.open(null, data, asset), extra);
} catch (e) {
callback(e);
}
}
};
handler.load(null, onLoad, asset);
},

_onSuccess: function (key, result, extra) {
this._cache[key] = result;
for (var i = 0; i < this._requests[key].length; i++) {
Expand Down
69 changes: 34 additions & 35 deletions tests/bundles/test_bundle_loader.js
Expand Up @@ -69,13 +69,6 @@ describe('Test Bundle Loader', function () {
})
];

// setup cubemap correctly so faces load
var id = this.assets[7].id;
this.assets[5].loadFaces = true;
this.assets[5].data = {
textures: [id, id, id, id, id, id]
};

// expected types of asset types
this.expectedTypes = {
css: {
Expand Down Expand Up @@ -177,77 +170,83 @@ describe('Test Bundle Loader', function () {
var self = this;
var todo = 0;

self.app.assets.add(this.bundleAsset);
self.app.assets.load(this.bundleAsset);
todo++;

self.assets.forEach(function (asset) {
self.app.assets.add(asset);
self.app.assets.load(asset);
todo++;
});

self.app.assets.on('load', function () {
var onLoad = function () {
todo--;
if (todo === 0) {
self.assets.forEach(function (asset, index) {
expect(asset.resource).to.not.equal(null);
var resource = asset.type === 'cubemap' ? asset.resources[1] : asset.resource;
expect(resource).to.not.equal(null);
var expected = self.expectedTypes[asset.type];

if (expected.typeof) {
expect(typeof asset.resource).to.equal(expected.typeof);
expect(typeof resource).to.equal(expected.typeof);
}

if (expected.instanceof) {
expect(asset.resource instanceof expected.instanceof).to.equal(true);
expect(resource instanceof expected.instanceof).to.equal(true);
}

if (asset.type === 'font') {
expect(asset.resource.textures.length).to.equal(2);
expect(resource.textures.length).to.equal(2);
}
});
done();
}
});
});

it('should load assets from bundle without using web workers', function (done) {
pc.platform.workers = false;

var self = this;
var todo = 0;
};

this.bundleAsset.on('load', onLoad);
self.app.assets.add(this.bundleAsset);
self.app.assets.load(this.bundleAsset);
todo++;

self.assets.forEach(function (asset) {
asset.on('load', onLoad);
self.app.assets.add(asset);
self.app.assets.load(asset);
todo++;
});
});

it('should load assets from bundle without using web workers', function (done) {
pc.platform.workers = false;

self.app.assets.on('load', function () {
var self = this;
var todo = 0;

var onLoad = function () {
todo--;
if (todo === 0) {
self.assets.forEach(function (asset, index) {
expect(asset.resource).to.not.equal(null);
var resource = asset.type === 'cubemap' ? asset.resources[1] : asset.resource;
expect(resource).to.not.equal(null);
var expected = self.expectedTypes[asset.type];

if (expected.typeof) {
expect(typeof asset.resource).to.equal(expected.typeof);
expect(typeof resource).to.equal(expected.typeof);
}

if (expected.instanceof) {
expect(asset.resource instanceof expected.instanceof).to.equal(true);
expect(resource instanceof expected.instanceof).to.equal(true);
}

if (asset.type === 'font') {
expect(asset.resource.textures.length).to.equal(2);
expect(resource.textures.length).to.equal(2);
}
});
done();
}
};

this.bundleAsset.on('load', onLoad);
self.app.assets.add(this.bundleAsset);
self.app.assets.load(this.bundleAsset);
todo++;

self.assets.forEach(function (asset) {
asset.on('load', onLoad);
self.app.assets.add(asset);
self.app.assets.load(asset);
todo++;
});
});

Expand Down
4 changes: 2 additions & 2 deletions tools/viewer/index.html
Expand Up @@ -4,12 +4,13 @@
<title>PlayCanvas Glb Viewer</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">
<link rel="icon" type="image/png" href="../playcanvas-favicon.png" />
<link rel="icon" type="image/png" href="../playcanvas-logo.png" />
<link rel="stylesheet" href="style.css">
<script src="../../build/playcanvas.js"></script>
<script src="../../build/playcanvas-extras.js"></script>
<script src="../../examples/assets/scripts/parsers/hdr-texture.js"></script>
<script src="../../examples/assets/scripts/utils/download-texture.js"></script>
<script src="../../examples/wasm-loader.js"></script>
</head>

<body onload="main()">
Expand Down Expand Up @@ -59,7 +60,6 @@ <h3>MORPH TARGETS</h3>
<!-- The canvas element -->
<canvas id="application-canvas"></canvas>
</div>
<script src="../../examples/wasm-loader.js"></script>
<script src="./src/viewer.js"></script>
<script src="./src/controls.js"></script>
<script src="./src/graph.js"></script>
Expand Down
48 changes: 18 additions & 30 deletions tools/viewer/src/viewer.js
Expand Up @@ -340,42 +340,30 @@ Object.assign(Viewer.prototype, {
var cubemap = new pc.Asset('helipad', 'cubemap', {
url: assetsFolder + "/cubemaps/Helipad.dds"
}, {
textures: [
assetsFolder + "/cubemaps/Helipad_posx.png",
assetsFolder + "/cubemaps/Helipad_negx.png",
assetsFolder + "/cubemaps/Helipad_posy.png",
assetsFolder + "/cubemaps/Helipad_negy.png",
assetsFolder + "/cubemaps/Helipad_posz.png",
assetsFolder + "/cubemaps/Helipad_negz.png"
],
magFilter: pc.FILTER_LINEAR,
minFilter: pc.FILTER_LINEAR_MIPMAP_LINEAR,
anisotropy: 1,
type: pc.TEXTURETYPE_RGBM
});
cubemap.loadFaces = true;
cubemap.on('load', function () {
if (cubemap.resource.width != 4) {
cubemap.resource.type = pc.TEXTURETYPE_RGBM;
app.scene.gammaCorrection = pc.GAMMA_SRGB;
app.scene.toneMapping = pc.TONEMAP_ACES;
app.scene.skyboxMip = 0; // Set the skybox to the 128x128 cubemap mipmap level
app.scene.setSkybox(cubemap.resources);
app.renderNextFrame = true; // ensure we render again when the cubemap arrives

// generate Helipad_equi.png from cubemaps
// reproject the heli to equirect
// var equi = new pc.Texture(app.graphicsDevice, {
// name: 'heli_equirect',
// width: 2048,
// height: 1024,
// type: pc.TEXTURETYPE_RGBM
// });
// pc.reprojectTexture(app.graphicsDevice, cubemap.resource, equi);
// pc.downloadTexture(equi, 'Helipad_equi.png', 0, true);

// pc.downloadTexture(cubemap.resource, 'Helipad_cube.png');
}
app.scene.gammaCorrection = pc.GAMMA_SRGB;
app.scene.toneMapping = pc.TONEMAP_ACES;
app.scene.skyboxMip = 1; // Set the skybox to the 128x128 cubemap mipmap level
app.scene.setSkybox(cubemap.resources);
app.renderNextFrame = true; // ensure we render again when the cubemap arrives

// generate Helipad_equi.png from cubemaps
// reproject the heli to equirect
// var equi = new pc.Texture(app.graphicsDevice, {
// name: 'heli_equirect',
// width: 2048,
// height: 1024,
// type: pc.TEXTURETYPE_RGBM
// });
// pc.reprojectTexture(app.graphicsDevice, cubemap.resource, equi);
// pc.downloadTexture(equi, 'Helipad_equi.png', 0, true);

// pc.downloadTexture(cubemap.resource, 'Helipad_cube.png');
});
app.assets.add(cubemap);
app.assets.load(cubemap);
Expand Down