ModelHandle/source/model/material.js
2021-12-28 16:44:00 +01:00

357 lines
7.9 KiB
JavaScript

OV.Color = class
{
constructor (r, g, b)
{
this.r = r; // 0 .. 255
this.g = g; // 0 .. 255
this.b = b; // 0 .. 255
}
Set (r, g, b)
{
this.r = r;
this.g = g;
this.b = b;
}
Clone ()
{
return new OV.Color (this.r, this.g, this.b);
}
};
OV.TextureMap = class
{
constructor ()
{
this.name = null;
this.url = null;
this.buffer = null;
this.offset = new OV.Coord2D (0.0, 0.0);
this.scale = new OV.Coord2D (1.0, 1.0);
this.rotation = 0.0; // radians
}
IsValid ()
{
return this.name !== null && this.url !== null && this.buffer !== null;
}
HasTransformation ()
{
if (!OV.CoordIsEqual2D (this.offset, new OV.Coord2D (0.0, 0.0))) {
return true;
}
if (!OV.CoordIsEqual2D (this.scale, new OV.Coord2D (1.0, 1.0))) {
return true;
}
if (!OV.IsEqual (this.rotation, 0.0)) {
return true;
}
return false;
}
IsEqual (rhs)
{
if (this.name !== rhs.name) {
return false;
}
if (this.name !== rhs.name) {
return false;
}
if (this.url !== rhs.url) {
return false;
}
if (!OV.CoordIsEqual2D (this.offset, rhs.offset)) {
return false;
}
if (!OV.CoordIsEqual2D (this.scale, rhs.scale)) {
return false;
}
if (!OV.IsEqual (this.rotation, rhs.rotation)) {
return false;
}
return true;
}
};
OV.TextureMapIsEqual = function (aTex, bTex)
{
if (aTex === null && bTex === null) {
return true;
} else if (aTex === null || bTex === null) {
return false;
}
return aTex.IsEqual (bTex);
};
OV.MaterialType =
{
Phong : 1,
Physical : 2
};
OV.MaterialBase = class
{
constructor (type)
{
this.type = type;
this.isDefault = false;
this.name = '';
this.color = new OV.Color (0, 0, 0);
this.vertexColors = false;
}
IsEqual (rhs)
{
if (this.type !== rhs.type) {
return false;
}
if (this.isDefault !== rhs.isDefault) {
return false;
}
if (this.name !== rhs.name) {
return false;
}
if (!OV.ColorIsEqual (this.color, rhs.color)) {
return false;
}
if (this.vertexColors !== rhs.vertexColors) {
return false;
}
return true;
}
};
OV.FaceMaterial = class extends OV.MaterialBase
{
constructor (type)
{
super (type);
this.emissive = new OV.Color (0, 0, 0);
this.opacity = 1.0; // 0.0 .. 1.0
this.transparent = false;
this.diffuseMap = null;
this.bumpMap = null;
this.normalMap = null;
this.emissiveMap = null;
this.alphaTest = 0.0; // 0.0 .. 1.0
this.multiplyDiffuseMap = false;
}
IsEqual (rhs)
{
if (!super.IsEqual (rhs)) {
return false;
}
if (!OV.ColorIsEqual (this.emissive, rhs.emissive)) {
return false;
}
if (!OV.IsEqual (this.opacity, rhs.opacity)) {
return false;
}
if (this.transparent !== rhs.transparent) {
return false;
}
if (!OV.TextureMapIsEqual (this.diffuseMap, rhs.diffuseMap)) {
return false;
}
if (!OV.TextureMapIsEqual (this.bumpMap, rhs.bumpMap)) {
return false;
}
if (!OV.TextureMapIsEqual (this.normalMap, rhs.normalMap)) {
return false;
}
if (!OV.TextureMapIsEqual (this.emissiveMap, rhs.emissiveMap)) {
return false;
}
if (!OV.IsEqual (this.alphaTest, rhs.alphaTest)) {
return false;
}
if (this.multiplyDiffuseMap !== rhs.multiplyDiffuseMap) {
return false;
}
return true;
}
EnumerateTextureMaps (enumerator)
{
if (this.diffuseMap !== null) {
enumerator (this.diffuseMap);
}
if (this.bumpMap !== null) {
enumerator (this.bumpMap);
}
if (this.normalMap !== null) {
enumerator (this.normalMap);
}
if (this.emissiveMap !== null) {
enumerator (this.emissiveMap);
}
}
};
OV.PhongMaterial = class extends OV.FaceMaterial
{
constructor ()
{
super (OV.MaterialType.Phong);
this.ambient = new OV.Color (0, 0, 0);
this.specular = new OV.Color (0, 0, 0);
this.shininess = 0.0; // 0.0 .. 1.0
this.specularMap = null;
}
IsEqual (rhs)
{
if (!super.IsEqual (rhs)) {
return false;
}
if (!OV.ColorIsEqual (this.ambient, rhs.ambient)) {
return false;
}
if (!OV.ColorIsEqual (this.specular, rhs.specular)) {
return false;
}
if (!OV.IsEqual (this.shininess, rhs.shininess)) {
return false;
}
if (!OV.TextureMapIsEqual (this.specularMap, rhs.specularMap)) {
return false;
}
return true;
}
EnumerateTextureMaps (enumerator)
{
super.EnumerateTextureMaps (enumerator);
if (this.specularMap !== null) {
enumerator (this.specularMap);
}
}
};
OV.PhysicalMaterial = class extends OV.FaceMaterial
{
constructor ()
{
super (OV.MaterialType.Physical);
this.metalness = 0.0; // 0.0 .. 1.0
this.roughness = 1.0; // 0.0 .. 1.0
this.metalnessMap = null;
}
IsEqual (rhs)
{
if (!super.IsEqual (rhs)) {
return false;
}
if (!OV.IsEqual (this.metalness, rhs.metalness)) {
return false;
}
if (!OV.IsEqual (this.roughness, rhs.roughness)) {
return false;
}
if (!OV.TextureMapIsEqual (this.metalnessMap, rhs.metalnessMap)) {
return false;
}
return true;
}
EnumerateTextureMaps (enumerator)
{
super.EnumerateTextureMaps (enumerator);
if (this.metalnessMap !== null) {
enumerator (this.metalnessMap);
}
}
};
OV.SRGBToLinear = function (component)
{
if (component < 0.04045) {
return component * 0.0773993808;
} else {
return Math.pow (component * 0.9478672986 + 0.0521327014, 2.4);
}
};
OV.LinearToSRGB = function (component)
{
if (component < 0.0031308) {
return component * 12.92;
} else {
return 1.055 * (Math.pow (component, 0.41666)) - 0.055;
}
};
OV.IntegerToHexString = function (intVal)
{
let result = parseInt (intVal, 10).toString (16);
while (result.length < 2) {
result = '0' + result;
}
return result;
};
OV.ColorToHexString = function (color)
{
let r = OV.IntegerToHexString (color.r);
let g = OV.IntegerToHexString (color.g);
let b = OV.IntegerToHexString (color.b);
return r + g + b;
};
OV.HexStringToColor = function (hexString)
{
if (hexString.length !== 6) {
return null;
}
let r = parseInt (hexString.substr (0, 2), 16);
let g = parseInt (hexString.substr (2, 2), 16);
let b = parseInt (hexString.substr (4, 2), 16);
return new OV.Color (r, g, b);
};
OV.ArrayToColor = function (arr)
{
return new OV.Color (arr[0], arr[1], arr[2]);
};
OV.ColorIsEqual = function (a, b)
{
return a.r === b.r && a.g === b.g && a.b === b.b;
};
OV.TextureIsEqual = function (a, b)
{
if (a.name !== b.name) {
return false;
}
if (a.name !== b.name) {
return false;
}
if (a.url !== b.url) {
return false;
}
if (!OV.CoordIsEqual2D (a.offset, b.offset)) {
return false;
}
if (!OV.CoordIsEqual2D (a.scale, b.scale)) {
return false;
}
if (!OV.IsEqual (a.rotation, b.rotation)) {
return false;
}
return true;
};