playcanvas / playcanvas/engine
Add toJSON for the assets
Nobody has claimed this yet.
- Dominant language
- JavaScript
- Stars
- 16.8k
- Forks
- 2k
- Avg merge
- 4h 32m
- Merged PRs (30d)
- 222
Description
It is good for all assets to have toJSON method, so that we can save and init the asset by data easily.
Here is my StandardMaterial.prototype.toJSON implementation:
import constants from './constants';
pc.StandardMaterial.prototype.toJSON = (function() {
var fields = [
'alphaTest', 'alphaToCoverage',
'ambient', 'ambientTint',
'aoMap', 'aoMapChannel', 'aoMapOffset', 'aoMapTiling',
'aoMapUv', 'aoMapVertexColor',
'blendType',
'bumpiness',
'conserveEnergy',
'cubeMap', 'cubeMapProjection', 'cubeMapProjectionBox',
'cull',
'depthTest', 'depthWrite', 'diffuse',
'diffuseMap', 'diffuseMapChannel', 'diffuseMapOffset', 'diffuseMapTiling',
'diffuseMapTint', 'diffuseMapUv', 'diffuseMapVertexColor',
'emissive', 'emissiveIntensity', 'emissiveMap',
'emissiveMapChannel', 'emissiveMapOffset', 'emissiveMapTiling',
'emissiveMapTint', 'emissiveMapUv', 'emissiveMapVertexColor',
'fresnelModel',
'glossMap', 'glossMapChannel', 'glossMapOffset', 'glossMapTiling',
'glossMapUv', 'glossMapVertexColor',
'heightMap', 'heightMapChannel', 'heightMapFactor',
'heightMapOffset', 'heightMapTiling', 'heightMapVertexColor', 'heightMapUv',
'lightMap', 'lightMapChannel', 'lightMapOffset',
'lightMapTiling', 'lightMapUv', 'lightMapVertexColor',
'metalness', 'metalnessMap', 'metalnessMapChannel',
'metalnessMapOffset', 'metalnessMapTiling',
'metalnessMapUv', 'metalnessMapVertexColor',
'name',
'normalMap', 'normalMapOffset', 'normalMapTiling',
'normalMapUv', 'normalMapVertexColor',
'occludeSpecular', 'occludeSpecularIntensity',
'opacity', 'opacityMap', 'opacityMapChannel',
'opacityMapOffset', 'opacityMapTiling',
'opacityMapUv', 'opacityMapVertexColor',
'reflectivity', 'refraction', 'refractionIndex',
'shadingModel',
'shadowSampleType',
'shininess',
'specular', 'specularAntialias', 'specularMap',
'specularMapChannel', 'specularMapOffset', 'specularMapTiling',
'specularMapTint', 'specularMapUv', 'specularMapVertexColor', 'sphereMap',
'useFog', 'useGammaTonemap', 'useLighting',
'useMetalness', 'useSkybox',
];
var defaultMaterial = toJSON.call(pc.ModelHandler.DEFAULT_MATERIAL);
function toJSON(options) {
var result = {};
var self = this;
if (typeof options === 'undefined') {
options = {};
}
fields.forEach(function(field) {
// texture
if (constants.MATERIAL_TEXTURE_FIELDS2[field]) {
if (self[field] !== null) {
result[field] = self[field].name;
} else {
result[field] = null;
}
// color or vector
} else if (constants.MATERIAL_ARRAY_FIELDS2[field]) {
result[field] = Array.from(self[field].data);
} else if (constants.MATERIAL_OBJECT_FIELDS2[field]) {
result[field] = self[field] ? self[field].toJSON() : null;
// primitive
} else {
// convert bumpiness to bumpMapFactor
if (field === 'bumpiness') {
result['bumpMapFactor'] = self[field];
} else {
result[field] = self[field];
}
}
});
if (options.diff) {
fields.forEach(function(field) {
if (field === 'bumpiness') {
field = 'bumpMapFactor';
}
var value1 = defaultMaterial[field];
var value2 = result[field];
// test two array is equal or not
if (constants.MATERIAL_ARRAY_FIELDS2[field]) {
value1 = value1.toString();
value2 = value2.toString();
}
if (constants.MATERIAL_OBJECT_FIELDS2[field]) {
value1 = JSON.stringify(value1);
value2 = JSON.stringify(value2);
}
if (value1 === value2) {
delete result[field];
}
});
}
return result;
}
return toJSON;
})();
And the constants:
var MATERIAL_TEXTURE_FIELDS = [
'aoMap', 'diffuseMap', 'glossMap', 'metalnessMap',
'specularMap', 'emissiveMap', 'opacityMap', 'lightMap',
'normalMap', 'heightMap', 'sphereMap', 'cubeMap'
];
var MATERIAL_TEXTURE_FIELDS2 = MATERIAL_TEXTURE_FIELDS.reduce(function(prev, next) {
prev[next] = true;
return prev;
}, {});
var MATERIAL_COLOR_FIELDS = [
'diffuse', 'specular', 'ambient', 'emissive'
];
var MATERIAL_VECTOR_FIELDS = [
// vec2
'diffuseMapOffset', 'diffuseMapTiling',
'opacityMapOffset', 'opacityMapTiling',
'aoMapOffset', 'aoMapTiling',
'specularMapOffset', 'specularMapTiling',
'metalnessMapOffset', 'metalnessMapTiling',
'glossMapOffset', 'glossMapTiling',
'heightMapOffset', 'heightMapTiling',
'emissiveMapOffset', 'emissiveMapTiling',
'normalMapOffset', 'normalMapTiling',
'lightMapOffset', 'lightMapTiling',
];
var MATERIAL_OBJECT_FIELDS = [
'cubeMapProjectionBox'
];
var MATERIAL_OBJECT_FIELDS2 = MATERIAL_OBJECT_FIELDS.reduce(function(prev, next) {
prev[next] = true;
return prev;
}, {});
var MATERIAL_ARRAY_FIELDS = MATERIAL_COLOR_FIELDS.concat(MATERIAL_VECTOR_FIELDS);
var MATERIAL_ARRAY_FIELDS2 = MATERIAL_ARRAY_FIELDS.reduce(function(prev, next) {
prev[next] = true;
return prev;
}, {});
export default {
MATERIAL_TEXTURE_FIELDS: MATERIAL_TEXTURE_FIELDS,
MATERIAL_TEXTURE_FIELDS2: MATERIAL_TEXTURE_FIELDS2,
MATERIAL_ARRAY_FIELDS: MATERIAL_ARRAY_FIELDS,
MATERIAL_ARRAY_FIELDS2: MATERIAL_ARRAY_FIELDS2,
MATERIAL_OBJECT_FIELDS: MATERIAL_OBJECT_FIELDS,
MATERIAL_OBJECT_FIELDS2: MATERIAL_OBJECT_FIELDS2,
};
We can call it by:
var mat = new pc.StandardMaterial();
mat.diffuse = new pc.Color(1,0,0,1);
mat.toJSON() // return the full json
/**
* { diffuse: [1, 0, 0, 1], diffuseMap: null, blendType: 0 ... }
*/
mat.toJSON({ diff: true }); // return the json different from mat.toJSON()
/**
* { diffuse: [1, 0, 0, 1] }
*/
We can add the same interface to other type of assets. 😃
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start by locating StandardMaterial.prototype.toJSON, the referenced constants, and pc.ModelHandler.DEFAULT_MATERIAL. Review how the proposed serialization distinguishes textures, arrays, objects, and primitive fields, then identify the other asset types that should expose the same interface. Done means assets can be serialized and initialized from JSON, including the proposed full and diff forms, with coverage for the supported asset types.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- javascript
- Domain
- computer-graphics
- Issue type
- Feature
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100