/*
This file contains proprietary software owned by Motorola Mobility, Inc.
No rights, expressed or implied, whatsoever to this software are provided by Motorola Mobility, Inc. hereunder.
(c) Copyright 2011 Motorola Mobility, Inc. All Rights Reserved.
*/
var MaterialParser = require("js/lib/rdge/materials/material-parser").MaterialParser;
var Material = require("js/lib/rdge/materials/material").Material;
var UberMaterial = function UberMaterial() {
///////////////////////////////////////////////////////////////////////
// Instance variables
///////////////////////////////////////////////////////////////////////
this._name = "UberMaterial";
this._shaderName = "uber";
this.getShaderName = function() { return this._shaderName; };
// set some default values
this._ambientColor = [ 0.0, 0.0, 0.0, 1.0 ];
this._diffuseColor = [ 1.0, 1.0, 1.0, 1.0 ];
this._specularColor = [ 1.0, 1.0, 1.0, 1.0 ];
this._specularPower = 32.0;
this._environmentAmount = 0.2; // 0 .. 1
// set the default maps
this._diffuseMapOb = { 'texture' : 'assets/images/rocky-diffuse.jpg', 'wrap' : 'REPEAT' };
this._normalMapOb = { 'texture' : 'assets/images/rocky-normal.jpg', 'wrap' : 'REPEAT' };
this._specularMapOb = { 'texture' : 'assets/images/rocky-spec.jpg', 'wrap' : 'REPEAT' };
this._environmentMapOb = { 'texture' : 'assets/images/silver.png', 'wrap' : 'CLAMP', 'envReflection' : this._environmentAmount };
this._useDiffuseMap = true;
this._useNormalMap = true;
this._useSpecularMap = true;
this._useEnvironmentMap = true;
this._useLights = [true, true, true, true];
this._MAX_LIGHTS = 4;
///////////////////////////////////////////////////////////////////////
// Material Property Accessors
///////////////////////////////////////////////////////////////////////
this._propNames = ["ambientColor", "diffuseColor", "specularColor", "specularPower" , "diffuseMap", "normalMap", "specularMap", "environmentMap", "environmentAmount" ];
this._propLabels = ["Ambient Color", "Diffuse Color", "Specular Color", "Specular Power", "Texture Map", "Bump Map", "Specular Map", "Environment Map", "Environment Map Amount" ];
this._propTypes = ["color", "color", "color", "float", "file", "file", "file", "file", "float" ];
this._propValues = [];
this._propValues[ this._propNames[0] ] = this._ambientColor.slice(0);
this._propValues[ this._propNames[1] ] = this._diffuseColor.slice(0);
this._propValues[ this._propNames[2] ] = this._specularColor.slice(0);
this._propValues[ this._propNames[3] ] = this._specularPower;
this._propValues[ this._propNames[4] ] = this._diffuseMapOb['texture'];
this._propValues[ this._propNames[5] ] = this._normalMapOb['texture'];
this._propValues[ this._propNames[6] ] = this._specularMapOb['texture'];
this._propValues[ this._propNames[7] ] = this._environmentMapOb['texture'];
this._propValues[ this._propNames[8] ] = this._environmentMapOb['envReflection'];
this.setProperty = function( prop, value ) {
if (prop == "color") prop = "ambientColor";
var valid = this.validateProperty( prop, value );
if (valid) {
this._propValues[prop] = value;
switch (prop)
{
case "diffuseMap":
this.updateDiffuseMap();
break;
case "normalMap":
this.updateNormalMap();
break;
case "specularMap":
this.updateSpecularMap();
break;
case "environmentMap":
this.updateEnvironmentMap();
break;
case "environmentAmount":
this.updateEnvironmentAmount( value );
break;
case "specularPower":
this.updateSpecularPower( value );
break;
case "ambientColor":
this.updateAmbientColor( value );
break;
case "diffuseColor":
this.updateDiffuseColor( value );
break;
case "specularColor":
this.updateSpecularColor( value );
break;
}
}
};
///////////////////////////////////////////////////////////////////////
// define the 4 lights
this._lights = [
{
'type' : 'point', // can be 'directional', 'point' or 'spot'
'spotInnerCutoff' : 14.0, // fragments in the inner cutoff 'cone' are full intensity.
'spotOuterCutoff' : 15.0, // fragments outside the outer cutoff 'cone' are unlit.
'position' : [ 8.0, 2.0, 8.0 ], // light position; ignored for directional lights
'direction' : [ -1.0, -1.0, -1.0 ], // light direction; ignored for point lights
'attenuation' : [ 1.0, 0.025, 0.00125 ], // light attenuation; constant, linear, quadratic
'diffuseColor' : [ 1.0, 0.5, 0.5, 1.0 ], // diffuse light color
'specularColor' : [ 1.0, 1.0, 1.0, 1.0 ] // specular light color
},
{
'type' : 'point',
'spotInnerCutoff' : 9.0,
'spotOuterCutoff' : 20.0,
'position' : [ -8.0, 2.0, 8.0 ],
'direction' : [ 1.0, -1.0, -1.0 ],
'attenuation' : [ 1.0, 0.025, 0.00125 ],
'diffuseColor' : [ 0.5, 1.0, 0.5, 1.0 ],
'specularColor' : [ 1.0, 1.0, 1.0, 1.0 ]
},
{
'type' : 'point',
'spotInnerCutoff' : 9.0,
'spotOuterCutoff' : 20.0,
'position' : [ -8.0, 2.0, -8.0 ],
'direction' : [ 1.0, -1.0, 1.0 ],
'attenuation' : [ 1.0, 0.25, 0.0125 ],
'diffuseColor' : [ 0.5, 0.5, 1.0, 1.0 ],
'specularColor' : [ 1.0, 1.0, 1.0, 1.0 ]
},
{
'type' : 'point',
'spotInnerCutoff' : 9.0,
'spotOuterCutoff' : 20.0,
'position' : [ 8.0, 4.0, -8.0 ],
'direction' : [ -1.0, -1.0, 1.0 ],
'attenuation' : [ 1.0, 0.25, 0.0125 ],
'diffuseColor' : [ 1.0, 1.0, 0.5, 1.0 ],
'specularColor' : [ 1.0, 1.0, 1.0, 1.0 ]
}
];
this._ubershaderCaps =
{
// ubershader material properties.
'material' : {
'ambientColor' : this._ambientColor, // material ambient color
'diffuseColor' : this._diffuseColor, // material diffuse color
'specularColor' : this._specularColor, // material specular color
'specularPower' : this._specularPower // material specular power (shininess)
},
// ubershader supports up to four lights.
'lighting' : {
'light0' : this._lights[0],
'light1' : this._lights[1],
'light2' : this._lights[2],
'light3' : this._lights[3]
},
// uvTransform can be used to scale or offset the texture coordinates.
'uvTransform' : [ 2.0, 0, 0, 0, 0, 2.0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 1],
// optional diffuse map
'diffuseMap' : this._diffuseMapOb,
// optional normal map
'normalMap' : this._normalMapOb,
// optional specular map
'specularMap' : this._specularMapOb,
// optional environment map
'environmentMap' : this._environmentMapOb
};
this.updateAmbientColor = function() {
this._ambientColor = this._propValues['ambientColor'].slice(0);
var material = this._materialNode;
if (material) {
var technique = material.shaderProgram.defaultTechnique;
technique.u_ambientColor.set(this._ambientColor);
}
};
this.updateDiffuseColor = function() {
this._diffuseColor = this._propValues['diffuseColor'].slice(0);
var material = this._materialNode;
if (material) {
var technique = material.shaderProgram.defaultTechnique;
technique.u_diffuseColor.set(this._diffuseColor);
}
};
this.updateSpecularColor = function( value ) {
this._specularColor = this._propValues['specularColor'];
var material = this._materialNode;
if (material) {
var technique = material.shaderProgram.defaultTechnique;
technique.u_specularColor.set(this._specularColor);
}
};
this.updateSpecularPower = function( value) {
this._specularPower = this._propValues['specularPower'];
var material = this._materialNode;
if (material)
{
var technique = material.shaderProgram.defaultTechnique;
technique.u_specularPower.set([this._specularPower]);
}
};
this.updateEnvironmentAmount = function(value) {
this._environmentMapOb.envReflectionAmount = value;
var material = this._materialNode;
if (material) {
var technique = material.shaderProgram.defaultTechnique;
technique.u_envReflection.set([this._environmentMapOb.envReflection]);
}
};
this.updateEnvironmentMap = function() {
var value = this._propValues[ "environmentMap" ];
this._environmentMapOb.texture = value;
if ((value == null) || (value.length == 0)) {
if (this._useEnvironmentMap) {
this._useEnvironmentMap = false;
this.rebuildShader();
}
} else {
if (!this._useEnvironmentMap) {
this._useEnvironmentMap = true;
this.rebuildShader();
} else {
var material = this._materialNode;
if (material) {
var technique = material.shaderProgram.defaultTechnique;
var renderer = g_Engine.getContext().renderer;
if (renderer && technique) {
var tex = renderer.getTextureByName(value, caps.environmentMap.wrap);
this.registerTexture( tex );
technique.s_environmentMap.set( tex );
}
}
}
}
};
this.updateDiffuseMap = function(value) {
var value = this._propValues[ "diffuseMap" ];
this._diffuseMapOb.texture = value;
if ((value == null) || (value.length == 0)) {
if (this._useDiffuseMap) {
this._useDiffuseMap = false;
this.rebuildShader();
}
} else {
if (!this._useDiffuseMap) {
this._useDiffuseMap = true;
this.rebuildShader();
} else {
var material = this._materialNode;
if (material) {
var technique = material.shaderProgram.defaultTechnique;
var renderer = g_Engine.getContext().renderer;
if (renderer && technique) {
var tex = renderer.getTextureByName(value, caps.diffuseMap.wrap);
this.registerTexture( tex );
technique.s_diffuseMap.set( tex );
}
}
}
}
};
this.updateSpecularMap = function() {
var value = this._propValues[ "specularMap" ];
this._specularMapOb.texture = value;
if ((value == null) || (value.length == 0)) {
if (this._useSpecularMap) {
this._useSpecularMap = false;
this.rebuildShader();
}
} else {
if (!this._useSpecularMap) {
this._useSpecularMap = true;
this.rebuildShader();
} else {
var material = this._materialNode;
if (material) {
var technique = material.shaderProgram.defaultTechnique;
var renderer = g_Engine.getContext().renderer;
if (renderer && technique) {
var tex = renderer.getTextureByName(value, caps.specularMap.wrap);
this.registerTexture( tex );
technique.s_specularMap.set( tex );
}
}
}
}
};
this.updateNormalMap = function(value) {
var value = this._propValues[ "normalMap" ];
this._normalMapOb.texture = value;
if ((value == null) || (value.length == 0)) {
if (this._useNormalMap) {
this._useNormalMap = false;
this.rebuildShader();
}
} else {
if (!this._useNormalMap) {
this._useNormalMap = true;
this.rebuildShader();
} else {
var material = this._materialNode;
if (material) {
var technique = material.shaderProgram.defaultTechnique;
var renderer = g_Engine.getContext().renderer;
if (renderer && technique) {
var tex = renderer.getTextureByName(value, caps.normalMap.wrap);
this.registerTexture( tex );
technique.s_normalMap.set( tex );
}
}
}
}
};
// duplcate method requirde
this.dup = function() {
// allocate a new uber material
var newMat = new UberMaterial();
newMat._useDiffuseMap = this._useDiffuseMap;
newMat._useEnvironmentMap = this._useEnvironmentMap;
newMat._useLights = this._useLights;
newMat._useNormalMap = this._useNormalMap;
newMat._useSpecularMap = this._useSpecularMap;
newMat.rebuildShader();
// copy over the current values;
var propNames = [], propValues = [], propTypes = [], propLabels = [];
this.getAllProperties( propNames, propValues, propTypes, propLabels);
var n = propNames.length;
for (var i=0; i 0)
{
this._ubershaderCaps.lighting =
{
'light0' : this._lights[0],
'light1' : this._lights[1],
'light2' : this._lights[2],
'light3' : this._lights[3]
}
}
}
var diffuseMap = pu.nextValue( "diffuseMap: " )
if(diffuseMap)
this.setProperty( "diffuseMap", diffuseMap );
var normalMap = pu.nextValue( "normalMap: " );
if(normalMap)
this.setProperty( "normalMap", normalMap );
var specularMap = pu.nextValue( "specularMap: " );
if(specularMap)
this.setProperty( "specularMap", specularMap );
var environmentMap = pu.nextValue( "environmentMap: " );
if(environmentMap)
{
this.setProperty( "environmentMap", environmentMap );
this.setProperty( "environmentAmount", Number( pu.nextValue( "envReflection" ) ) );
}
this.rebuildShader();
}
this.export = function()
{
// every material needs the base type and instance name
var exportStr = "material: " + this.getShaderName() + "\n";
exportStr += "name: " + this.getName() + "\n";
var caps = this._ubershaderCaps;
// export the material properties
if (typeof caps.material != 'undefined')
{
exportStr += "materialProps: true\n";
exportStr += "ambientColor: " + caps.material.ambientColor + "\n";
exportStr += "diffuseColor: " + caps.material.diffuseColor + "\n";
exportStr += "specularColor: " + caps.material.specularColor + "\n";
exportStr += "specularPower: " + caps.material.specularPower + "\n";
}
if (typeof caps.lighting != 'undefined')
{
exportStr += "lightProps: true\n";
var light = caps.lighting['light' + i];
for (var i=0; i