using System;
using System.Collections.Generic;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Text;
namespace Ohana3DS_Rebirth.Ohana
{
public class RenderBase
{
///
/// 2-D Vector.
///
public class OVector2
{
public float x;
public float y;
///
/// Creates a new 2-D Vector.
///
/// The X position
/// The Y position
public OVector2(float _x, float _y)
{
x = _x;
y = _y;
}
///
/// Creates a new 2-D Vector.
///
/// The 2-D Vector
public OVector2(OVector2 vector)
{
x = vector.x;
y = vector.y;
}
///
/// Creates a new 2-D Vector.
///
public OVector2()
{
}
///
/// Writes the Vector to a Stream using a BinaryWriter.
///
/// The Writer of the output Stream
public void write(BinaryWriter output)
{
output.Write(x);
output.Write(y);
}
public override bool Equals(object obj)
{
if (obj == null) return false;
return this == (OVector2)obj;
}
public override int GetHashCode()
{
return x.GetHashCode() ^
y.GetHashCode();
}
public static bool operator ==(OVector2 a, OVector2 b)
{
return a.x == b.x && a.y == b.y;
}
public static bool operator !=(OVector2 a, OVector2 b)
{
return !(a == b);
}
public override string ToString()
{
return string.Format("X:{0}; Y:{1}", x, y);
}
}
///
/// 3-D Vector.
///
public class OVector3
{
public float x;
public float y;
public float z;
///
/// Creates a new 3-D Vector.
///
/// The X position
/// The Y position
/// The Z position
public OVector3(float _x, float _y, float _z)
{
x = _x;
y = _y;
z = _z;
}
///
/// Creates a new 3-D Vector.
///
/// The 3-D vector
public OVector3(OVector3 vector)
{
x = vector.x;
y = vector.y;
z = vector.z;
}
///
/// Creates a new 3-D Vector.
///
public OVector3()
{
}
///
/// Writes the Vector to a Stream using a BinaryWriter.
///
/// The Writer of the output Stream
public void write(BinaryWriter output)
{
output.Write(x);
output.Write(y);
output.Write(z);
}
///
/// Transform the 3-D Vector with a matrix.
///
/// Input vector
/// The matrix
///
public static OVector3 transform(OVector3 input, OMatrix matrix)
{
OVector3 output = new OVector3();
output.x = input.x * matrix.M11 + input.y * matrix.M21 + input.z * matrix.M31 + matrix.M41;
output.y = input.x * matrix.M12 + input.y * matrix.M22 + input.z * matrix.M32 + matrix.M42;
output.z = input.x * matrix.M13 + input.y * matrix.M23 + input.z * matrix.M33 + matrix.M43;
return output;
}
public override bool Equals(object obj)
{
if (obj == null) return false;
return this == (OVector3)obj;
}
public override int GetHashCode()
{
return x.GetHashCode() ^
y.GetHashCode() ^
z.GetHashCode();
}
public static OVector3 operator *(OVector3 a, float b)
{
return new OVector3(a.x * b, a.y * b, a.z * b);
}
public static OVector3 operator *(OVector3 a, OVector3 b)
{
return new OVector3(a.x * b.x, a.y * b.y, a.z * b.z);
}
public static OVector3 operator /(OVector3 a, float b)
{
return new OVector3(a.x / b, a.y / b, a.z / b);
}
public static bool operator ==(OVector3 a, OVector3 b)
{
return a.x == b.x && a.y == b.y && a.z == b.z;
}
public static bool operator !=(OVector3 a, OVector3 b)
{
return !(a == b);
}
public float length()
{
return (float)Math.Sqrt(dot(this, this));
}
public OVector3 normalize()
{
return this / length();
}
public static float dot(OVector3 a, OVector3 b)
{
float x = a.x * b.x;
float y = a.y * b.y;
float z = a.z * b.z;
return x + y + z;
}
public override string ToString()
{
return string.Format("X:{0}; Y:{1}; Z:{2}", x, y, z);
}
}
///
/// 4-D Vector.
///
public class OVector4
{
public float x;
public float y;
public float z;
public float w;
///
/// Creates a new 4-D Vector.
///
/// The X position
/// The Y position
/// The Z position
/// The W position
public OVector4(float _x, float _y, float _z, float _w)
{
x = _x;
y = _y;
z = _z;
w = _w;
}
///
/// Creates a new 4-D Vector.
///
/// The 4-D vector
public OVector4(OVector4 vector)
{
x = vector.x;
y = vector.y;
z = vector.z;
w = vector.w;
}
///
/// Creates a Quaternion from a Axis/Angle.
///
/// The Axis vector
/// The Angle
public OVector4(OVector3 vector, float angle)
{
x = (float)(Math.Sin(angle * 0.5f) * vector.x);
y = (float)(Math.Sin(angle * 0.5f) * vector.y);
z = (float)(Math.Sin(angle * 0.5f) * vector.z);
w = (float)Math.Cos(angle * 0.5f);
}
///
/// Creates a new 4-D Vector.
///
public OVector4()
{
}
///
/// Writes the Vector to a Stream using a BinaryWriter.
///
/// The Writer of the output Stream
public void write(BinaryWriter output)
{
output.Write(x);
output.Write(y);
output.Write(z);
output.Write(w);
}
///
/// Converts the Quaternion representation on this Vector to the Euler representation.
///
/// The Euler X, Y and Z rotation angles in radians
public OVector3 toEuler()
{
OVector3 output = new OVector3();
output.z = (float)Math.Atan2(2 * (x * y + z * w), 1 - 2 * (y * y + z * z));
output.y = -(float)Math.Asin(2 * (x * z - w * y));
output.x = (float)Math.Atan2(2 * (x * w + y * z), -(1 - 2 * (z * z + w * w)));
return output;
}
public override bool Equals(object obj)
{
if (obj == null) return false;
return this == (OVector4)obj;
}
public override int GetHashCode()
{
return x.GetHashCode() ^
y.GetHashCode() ^
z.GetHashCode() ^
w.GetHashCode();
}
public static OVector4 operator *(OVector4 a, float b)
{
return new OVector4(a.x * b, a.y * b, a.z * b, a.w * b);
}
public static OVector4 operator *(OVector4 a, OVector4 b)
{
return new OVector4(a.x * b.x, a.y * b.y, a.z * b.z, a.w * b.w);
}
public static bool operator ==(OVector4 a, OVector4 b)
{
return a.x == b.x && a.y == b.y && a.z == b.z && a.w == b.w;
}
public static bool operator !=(OVector4 a, OVector4 b)
{
return !(a == b);
}
public override string ToString()
{
return string.Format("X:{0}; Y:{1}; Z:{2}; W:{3}", x, y, z, w);
}
}
///
/// Vertex structure, used to specify data of the various attributes of a vertice on a mesh.
///
public class OVertex : IEquatable
{
public OVector3 position;
public OVector3 normal;
public OVector3 tangent;
public OVector2 texture0;
public OVector2 texture1;
public OVector2 texture2;
public List node;
public List weight;
public uint diffuseColor;
///
/// Creates a new Vertex.
///
public OVertex()
{
node = new List();
weight = new List();
position = new OVector3();
normal = new OVector3();
tangent = new OVector3();
texture0 = new OVector2();
texture1 = new OVector2();
texture2 = new OVector2();
}
///
/// Creates a new Vertex.
///
public OVertex(OVertex vertex)
{
node = new List();
weight = new List();
node.AddRange(vertex.node);
weight.AddRange(vertex.weight);
position = new OVector3(vertex.position);
normal = new OVector3(vertex.normal);
tangent = new OVector3(vertex.tangent);
texture0 = new OVector2(vertex.texture0);
texture1 = new OVector2(vertex.texture1);
texture2 = new OVector2(vertex.texture2);
}
///
/// Creates a new Vertex.
///
/// The position of the Vertex on the 3-D space
/// The normal Vector
/// The texture U/V coordinates
/// The diffuse color
public OVertex(OVector3 _position, OVector3 _normal, OVector2 _texture0, uint _color)
{
node = new List();
weight = new List();
position = new OVector3(_position);
normal = new OVector3(_normal);
texture0 = new OVector2(_texture0);
diffuseColor = _color;
}
///
/// Checks if two vertex are equal by comparing each element.
///
/// Vertex to compare
///
public bool Equals(OVertex vertex)
{
return position == vertex.position &&
normal == vertex.normal &&
tangent == vertex.tangent &&
texture0 == vertex.texture0 &&
texture1 == vertex.texture1 &&
texture2 == vertex.texture2 &&
node.SequenceEqual(vertex.node) &&
weight.SequenceEqual(vertex.weight) &&
diffuseColor == vertex.diffuseColor;
}
}
///
/// Matrix, used to transform vertices on a model.
/// Transformations includes rotation, translation and scaling.
///
public class OMatrix
{ //4x4
float[,] matrix;
public OMatrix()
{
matrix = new float[4, 4];
matrix[0, 0] = 1.0f;
matrix[1, 1] = 1.0f;
matrix[2, 2] = 1.0f;
matrix[3, 3] = 1.0f;
}
public float M11 { get { return matrix[0, 0]; } set { matrix[0, 0] = value; } }
public float M12 { get { return matrix[0, 1]; } set { matrix[0, 1] = value; } }
public float M13 { get { return matrix[0, 2]; } set { matrix[0, 2] = value; } }
public float M14 { get { return matrix[0, 3]; } set { matrix[0, 3] = value; } }
public float M21 { get { return matrix[1, 0]; } set { matrix[1, 0] = value; } }
public float M22 { get { return matrix[1, 1]; } set { matrix[1, 1] = value; } }
public float M23 { get { return matrix[1, 2]; } set { matrix[1, 2] = value; } }
public float M24 { get { return matrix[1, 3]; } set { matrix[1, 3] = value; } }
public float M31 { get { return matrix[2, 0]; } set { matrix[2, 0] = value; } }
public float M32 { get { return matrix[2, 1]; } set { matrix[2, 1] = value; } }
public float M33 { get { return matrix[2, 2]; } set { matrix[2, 2] = value; } }
public float M34 { get { return matrix[2, 3]; } set { matrix[2, 3] = value; } }
public float M41 { get { return matrix[3, 0]; } set { matrix[3, 0] = value; } }
public float M42 { get { return matrix[3, 1]; } set { matrix[3, 1] = value; } }
public float M43 { get { return matrix[3, 2]; } set { matrix[3, 2] = value; } }
public float M44 { get { return matrix[3, 3]; } set { matrix[3, 3] = value; } }
public float this[int col, int row]
{
get
{
return matrix[col, row];
}
set
{
matrix[col, row] = value;
}
}
public static OMatrix operator *(OMatrix a, OMatrix b)
{
OMatrix c = new OMatrix();
for (int i = 0; i < 4; i++)
{
for (int j = 0; j < 4; j++)
{
float sum = 0;
for (int k = 0; k < 4; k++)
{
sum += a[i, k] * b[k, j];
}
c[i, j] = sum;
}
}
return c;
}
///
/// Gets the Inverse of the Matrix.
///
///
public OMatrix invert()
{
float[,] opMatrix = new float[4, 8];
for (int N = 0; N < 4; N++)
{
for (int m = 0; m < 4; m++)
{
opMatrix[m, N] = matrix[m, N];
}
}
//Creates Identity at right side
for (int N = 0; N < 4; N++)
{
for (int m = 0; m < 4; m++)
{
if (N == m)
opMatrix[m, N + 4] = 1;
else
opMatrix[m, N + 4] = 0;
}
}
for (int k = 0; k < 4; k++)
{
if (opMatrix[k, k] == 0)
{
int row = 0;
for (int N = k; N < 4; N++) if (opMatrix[N, k] != 0) { row = N; break; }
for (int m = k; m < 8; m++)
{
float temp = opMatrix[k, m];
opMatrix[k, m] = opMatrix[row, m];
opMatrix[row, m] = temp;
}
}
float element = opMatrix[k, k];
for (int N = k; N < 8; N++) opMatrix[k, N] /= element;
for (int N = 0; N < 4; N++)
{
if (N == k && N == 3) break;
if (N == k && N < 3) N++;
if (opMatrix[N, k] != 0)
{
float multiplier = opMatrix[N, k] / opMatrix[k, k];
for (int m = k; m < 8; m++) opMatrix[N, m] -= opMatrix[k, m] * multiplier;
}
}
}
OMatrix output = new OMatrix();
output.M11 = opMatrix[0, 4];
output.M12 = opMatrix[0, 5];
output.M13 = opMatrix[0, 6];
output.M14 = opMatrix[0, 7];
output.M21 = opMatrix[1, 4];
output.M22 = opMatrix[1, 5];
output.M23 = opMatrix[1, 6];
output.M24 = opMatrix[1, 7];
output.M31 = opMatrix[2, 4];
output.M32 = opMatrix[2, 5];
output.M33 = opMatrix[2, 6];
output.M34 = opMatrix[2, 7];
output.M41 = opMatrix[3, 4];
output.M42 = opMatrix[3, 5];
output.M43 = opMatrix[3, 6];
output.M44 = opMatrix[3, 7];
return output;
}
///
/// Creates a scaling Matrix with a given 3-D proportion size.
///
/// The Scale proportions
///
public static OMatrix scale(OVector3 scale)
{
OMatrix output = new OMatrix
{
M11 = scale.x,
M22 = scale.y,
M33 = scale.z
};
return output;
}
///
/// Creates a scaling Matrix with a given 2-D proportion size.
///
/// The Scale proportions
///
public static OMatrix scale(OVector2 scale)
{
OMatrix output = new OMatrix
{
M11 = scale.x,
M22 = scale.y
};
return output;
}
///
/// Uniform scales the X/Y/Z axis with the same value.
///
/// The Scale proportion
///
public static OMatrix scale(float scale)
{
OMatrix output = new OMatrix
{
M11 = scale,
M22 = scale,
M33 = scale
};
return output;
}
///
/// Rotates about the X axis.
///
/// Angle in radians
///
public static OMatrix rotateX(float angle)
{
OMatrix output = new OMatrix
{
M22 = (float)Math.Cos(angle),
M32 = -(float)Math.Sin(angle),
M23 = (float)Math.Sin(angle),
M33 = (float)Math.Cos(angle)
};
return output;
}
///
/// Rotates about the Y axis.
///
/// Angle in radians
///
public static OMatrix rotateY(float angle)
{
OMatrix output = new OMatrix
{
M11 = (float)Math.Cos(angle),
M31 = (float)Math.Sin(angle),
M13 = -(float)Math.Sin(angle),
M33 = (float)Math.Cos(angle)
};
return output;
}
///
/// Rotates about the Z axis.
///
/// Angle in radians
///
public static OMatrix rotateZ(float angle)
{
OMatrix output = new OMatrix
{
M11 = (float)Math.Cos(angle),
M21 = -(float)Math.Sin(angle),
M12 = (float)Math.Sin(angle),
M22 = (float)Math.Cos(angle)
};
return output;
}
///
/// Creates a translation Matrix with the given 3-D position offset.
///
/// The Position offset
///
public static OMatrix translate(OVector3 position)
{
OMatrix output = new OMatrix
{
M41 = position.x,
M42 = position.y,
M43 = position.z
};
return output;
}
///
/// Creates a translation Matrix with the given 2-D position offset.
///
/// The Position offset
///
public static OMatrix translate(OVector2 position)
{
OMatrix output = new OMatrix
{
M31 = position.x,
M32 = position.y
};
return output;
}
public override string ToString()
{
StringBuilder SB = new StringBuilder();
for (int Row = 0; Row < 3; Row++)
{
for (int Col = 0; Col < 4; Col++)
{
SB.Append(string.Format("M{0}{1}: {2,-16}", Row + 1, Col + 1, this[Col, Row]));
}
SB.Append(Environment.NewLine);
}
return SB.ToString();
}
}
///
/// Oriented Bounding Box, can be used for collision testing.
///
public class OOrientedBoundingBox
{
public string name;
public OVector3 centerPosition;
public OMatrix orientationMatrix;
public OVector3 size;
public OOrientedBoundingBox()
{
orientationMatrix = new OMatrix();
}
}
///
/// Translucency kind of a mesh.
///
public enum OTranslucencyKind
{
opaque = 0,
translucent = 1,
subtractive = 2,
additive = 3
}
///
/// Skinning mode used on the Skeleton. Smooth skinning allows multiple bones (max 4) per vertex.
/// Other bones allows only one bone, and meshes are on their relative positions by default.
///
public enum OSkinningMode
{
none = 0,
smoothSkinning = 1,
rigidSkinning = 2
}
///
/// Mesh of a model. A model is usually composed of several meshes.
/// For example, a human character may have one mesh for the head, other for the body, other for members and so on...
///
public class OMesh
{
public List vertices;
public ushort materialId;
public ushort renderPriority;
public string name;
public bool isVisible;
public OOrientedBoundingBox boundingBox;
public bool hasNormal;
public bool hasTangent;
public bool hasColor;
public bool hasNode;
public bool hasWeight;
public int texUVCount;
public OMesh()
{
vertices = new List();
boundingBox = new OOrientedBoundingBox();
isVisible = true;
}
}
///
/// Billboard mode used on the Skeleton.
///
public enum OBillboardMode
{
off = 0,
world = 2,
worldViewpoint = 3,
screen = 4,
screenViewpoint = 5,
yAxial = 6,
yAxialViewpoint = 7
}
///
/// Bone of the skeleton. All values are relative to the parent bone.
///
public class OBone
{
public OVector3 translation;
public OVector3 rotation;
public OVector3 scale;
public OVector3 absoluteScale;
public OMatrix invTransform;
public short parentId;
public string name = null;
public OBillboardMode billboardMode;
public bool isSegmentScaleCompensate;
public List userData;
///
/// Creates a new Bone.
///
public OBone()
{
translation = new OVector3();
rotation = new OVector3();
scale = new OVector3();
userData = new List();
}
}
///
/// The several colors contained in one Material.
///
public struct OMaterialColor
{
public Color emission;
public Color ambient;
public Color diffuse;
public Color specular0;
public Color specular1;
public Color constant0;
public Color constant1;
public Color constant2;
public Color constant3;
public Color constant4;
public Color constant5;
public float colorScale;
}
///
/// Culling mode of a mesh.
/// It is used to draw in clockwise or counter-clockwise direction.
///
public enum OCullMode
{
never = 0,
frontFace = 1,
backFace = 2
}
///
/// Rasterization stage parameters.
///
public struct ORasterization
{
public OCullMode cullMode;
public bool isPolygonOffsetEnabled;
public float polygonOffsetUnit;
}
///
/// Filtering mode used when the rendered texture is smaller than the normal texture.
/// ex: Object is too far from the Point of View.
///
public enum OTextureMinFilter
{
nearestMipmapNearest = 1,
nearestMipmapLinear = 2,
linearMipmapNearest = 4,
linearMipmapLinear = 5
}
///
/// Filtering mode used when the rendered texture is bigger than the normal texture.
/// ex: Object is too close to the Point of View.
///
public enum OTextureMagFilter
{
nearest = 0,
linear = 1
}
///
/// Wrapping mode when the UV is outside of 0...1 range.
///
public enum OTextureWrap
{
clampToEdge = 0,
clampToBorder = 1,
repeat = 2,
mirroredRepeat = 3
}
///
/// Projection used on texture mapping.
///
public enum OTextureProjection
{
uvMap = 0,
cameraCubeMap = 1,
cameraSphereMap = 2,
projectionMap = 3,
shadowMap = 4,
shadowCubeMap = 5
}
///
/// Type of a constant color.
///
public enum OConstantColor
{
constant0 = 0,
constant1 = 1,
constant2 = 2,
constant3 = 3,
constant4 = 4,
constant5 = 5,
emission = 6,
ambient = 7,
diffuse = 8,
specular0 = 9,
specular1 = 0xa,
}
///
/// Operation done on the TevStage on Fragment Shader.
///
public enum OCombineOperator
{
replace = 0,
modulate = 1,
add = 2,
addSigned = 3,
interpolate = 4,
subtract = 5,
dot3Rgb = 6,
dot3Rgba = 7,
multiplyAdd = 8,
addMultiply = 9
}
///
/// Input color of the operation done on Fragment Shader.
///
public enum OCombineSource
{
primaryColor = 0,
fragmentPrimaryColor = 1,
fragmentSecondaryColor = 2,
texture0 = 3,
texture1 = 4,
texture2 = 5,
texture3 = 6,
previousBuffer = 0xd,
constant = 0xe,
previous = 0xf
}
///
/// Input components of the color on operation done on Fragment Shader.
///
public enum OCombineOperandRgb
{
color = 0,
oneMinusColor = 1,
alpha = 2,
oneMinusAlpha = 3,
red = 4,
oneMinusRed = 5,
green = 8,
oneMinusGreen = 9,
blue = 0xc,
oneMinusBlue = 0xd
}
///
/// Input components of the alpha color on operation done on Fragment Shader.
///
public enum OCombineOperandAlpha
{
alpha = 0,
oneMinusAlpha = 1,
red = 2,
oneMinusRed = 3,
green = 4,
oneMinusGreen = 5,
blue = 6,
oneMinusBlue = 7
}
///
/// Parameters used to transform textures.
///
public struct OTextureCoordinator
{
public OTextureProjection projection;
public uint referenceCamera;
public float scaleU, scaleV;
public float rotate;
public float translateU, translateV;
}
///
/// Parameters used to map textures on the surface.
///
public struct OTextureMapper
{
public OTextureMinFilter minFilter;
public OTextureMagFilter magFilter;
public OTextureWrap wrapU, wrapV;
public uint minLOD;
public float LODBias;
public Color borderColor;
}
///
/// Which texture is used as Bump Map?
///
public enum OBumpTexture
{
texture0 = 0,
texture1 = 1,
texture2 = 2,
texture3 = 3
}
///
/// Bump mode, how the bump texture is used.
///
public enum OBumpMode
{
notUsed = 0,
asBump = 1,
asTangent = 2
}
///
/// Fragment Shader bump parameters.
///
public struct OFragmentBump
{
public OBumpTexture texture;
public OBumpMode mode;
public bool isBumpRenormalize;
}
///
/// Fresnel related configuration.
///
public enum OFresnelConfig
{
none = 0,
primary = 1,
secondary = 2,
primarySecondary = 3
}
///
/// Value used as input of 1-D LUT on the Fragment Shader lighting.
///
public enum OFragmentSamplerInput
{
halfNormalCosine = 0, //N·H
halfViewCosine = 1, //V·H
viewNormalCosine = 2, //N·V
normalLightCosine = 3, //L·N
spotLightCosine = 4, //-L·P
phiCosine = 5 //cosϕ
}
///
/// Multiplier for the Input value on Fragment Shader.
///
public enum OFragmentSamplerScale
{
one = 0,
two = 1,
four = 2,
eight = 3,
quarter = 6,
half = 7
}
///
/// Fragment Shader lighting LUT parameters.
///
public struct OFragmentSampler
{
public bool isAbsolute;
public OFragmentSamplerInput input;
public OFragmentSamplerScale scale;
public string samplerName;
public string tableName; //LookUp Table
}
///
/// Fragment Shader lighting parameters.
///
public struct OFragmentLighting
{
public OFresnelConfig fresnelConfig;
public bool isClampHighLight;
public bool isDistribution0Enabled;
public bool isDistribution1Enabled;
public bool isGeometryFactor0Enabled;
public bool isGeometryFactor1Enabled;
public bool isReflectionEnabled;
public OFragmentSampler reflectanceRSampler;
public OFragmentSampler reflectanceGSampler;
public OFragmentSampler reflectanceBSampler;
public OFragmentSampler distribution0Sampler;
public OFragmentSampler distribution1Sampler;
public OFragmentSampler fresnelSampler;
}
///
/// Texture blending TevStages parameters.
///
public class OTextureCombiner
{
public ushort rgbScale, alphaScale;
public OConstantColor constantColor;
public OCombineOperator combineRgb, combineAlpha;
public OCombineSource[] rgbSource;
public OCombineOperandRgb[] rgbOperand;
public OCombineSource[] alphaSource;
public OCombineOperandAlpha[] alphaOperand;
public OTextureCombiner()
{
rgbSource = new OCombineSource[3];
rgbOperand = new OCombineOperandRgb[3];
alphaSource = new OCombineSource[3];
alphaOperand = new OCombineOperandAlpha[3];
}
}
///
/// Alpha testing parameters.
///
public struct OAlphaTest
{
public bool isTestEnabled;
public OTestFunction testFunction;
public uint testReference;
}
///
/// Fragment shader parameters.
///
public class OFragmentShader
{
public uint layerConfig;
public Color bufferColor;
public OFragmentBump bump;
public OFragmentLighting lighting;
public OTextureCombiner[] textureCombiner;
public OAlphaTest alphaTest;
public OFragmentShader()
{
textureCombiner = new OTextureCombiner[6];
for (int i = 0; i < 6; i++) textureCombiner[i] = new OTextureCombiner();
}
}
///
/// Comparator used on test functions.
///
public enum OTestFunction
{
never = 0,
always = 1,
equal = 2,
notEqual = 3,
less = 4,
lessOrEqual = 5,
greater = 6,
greaterOrEqual = 7
}
///
/// Depth operation parameters.
///
public struct ODepthOperation
{
public bool isTestEnabled;
public OTestFunction testFunction;
public bool isMaskEnabled;
}
///
/// Blending mode used on Alpha Blending.
///
public enum OBlendMode
{
logical = 0,
notUsed = 2,
blend = 3
}
///
/// Binary logical operations.
///
public enum OLogicalOperation
{
clear = 0,
and = 1,
andReverse = 2,
copy = 3,
set = 4,
copyInverted = 5,
noOperation = 6,
invert = 7,
notAnd = 8,
or = 9,
notOr = 0xa,
exclusiveOr = 0xb,
equiv = 0xc,
andInverted = 0xd,
orReverse = 0xe,
orInverted = 0xf
}
///
/// Alpha blending functions.
///
public enum OBlendFunction
{
zero = 0,
one = 1,
sourceColor = 2,
oneMinusSourceColor = 3,
destinationColor = 4,
oneMinusDestinationColor = 5,
sourceAlpha = 6,
oneMinusSourceAlpha = 7,
destinationAlpha = 8,
oneMinusDestinationAlpha = 9,
constantColor = 0xa,
oneMinusConstantColor = 0xb,
constantAlpha = 0xc,
oneMinusConstantAlpha = 0xd,
sourceAlphaSaturate = 0xe
}
///
/// Blending equations.
///
public enum OBlendEquation
{
add = 0,
subtract = 1,
reverseSubtract = 2,
min = 3,
max = 4
}
///
/// Blending operation parameters.
///
public struct OBlendOperation
{
public OBlendMode mode;
public OLogicalOperation logicalOperation;
public OBlendFunction rgbFunctionSource, rgbFunctionDestination;
public OBlendEquation rgbBlendEquation;
public OBlendFunction alphaFunctionSource, alphaFunctionDestination;
public OBlendEquation alphaBlendEquation;
public Color blendColor;
}
///
/// Stencil operation operation.
///
public enum OStencilOp
{
keep = 0,
zero = 1,
replace = 2,
increase = 3,
decrease = 4,
increaseWrap = 5,
decreaseWrap = 6
}
///
/// Stencil operation parameters.
///
public struct OStencilOperation
{
public bool isTestEnabled;
public OTestFunction testFunction;
public uint testReference;
public uint testMask;
public OStencilOp failOperation;
public OStencilOp zFailOperation;
public OStencilOp passOperation;
}
///
/// Fragment operations (Stencil, blending, depth).
///
public struct OFragmentOperation
{
public ODepthOperation depth;
public OBlendOperation blend;
public OStencilOperation stencil;
}
///
/// The input format is the following: Id@Name.
/// The Id is used to choose data inside the group "Name", Id can be another name or an index.
/// The group may be a model, with Id being a Material, a Shader group with Id being the shader, and so on...
///
public class OReference
{
public string id;
public string name;
///
/// Creates a new Reference.
///
/// Reference Identification string
/// Reference name
public OReference(string _id, string _name)
{
id = _id;
name = _name;
}
///
/// Creates a new Reference.
///
/// String of reference on Id@Name format
public OReference(string _name)
{
if (_name == null) return;
if (_name.Contains("@"))
{
string[] names = _name.Split(Convert.ToChar("@"));
id = names[0];
name = names[1];
}
else
{
name = _name;
}
}
///
/// Creates a new Reference.
///
public OReference()
{
}
public override string ToString()
{
return id + "@" + name;
}
}
///
/// Material parameters.
/// It have references to textures, parameters used for blending said textures, and other Fragment Shader related data.
///
public class OMaterial
{
public string name, name0, name1, name2;
public OReference shaderReference, modelReference;
public List userData;
public OMaterialColor materialColor;
public ORasterization rasterization;
public OTextureCoordinator[] textureCoordinator;
public OTextureMapper[] textureMapper;
public OFragmentShader fragmentShader;
public OFragmentOperation fragmentOperation;
public uint lightSetIndex;
public uint fogIndex;
public bool isFragmentLightEnabled;
public bool isVertexLightEnabled;
public bool isHemiSphereLightEnabled;
public bool isHemiSphereOcclusionEnabled;
public bool isFogEnabled;
public OMaterial()
{
userData = new List();
textureCoordinator = new OTextureCoordinator[3];
textureMapper = new OTextureMapper[3];
fragmentShader = new OFragmentShader();
name = "material";
fragmentShader.alphaTest.isTestEnabled = true;
fragmentShader.alphaTest.testFunction = OTestFunction.greater;
textureMapper[0].wrapU = OTextureWrap.repeat;
textureMapper[0].wrapV = OTextureWrap.repeat;
textureMapper[0].minFilter = OTextureMinFilter.linearMipmapLinear;
textureMapper[0].magFilter = OTextureMagFilter.linear;
for (int i = 0; i < 6; i++)
{
fragmentShader.textureCombiner[i].rgbSource[0] = OCombineSource.texture0;
fragmentShader.textureCombiner[i].rgbSource[1] = OCombineSource.primaryColor;
fragmentShader.textureCombiner[i].combineRgb = OCombineOperator.modulate;
fragmentShader.textureCombiner[i].alphaSource[0] = OCombineSource.texture0;
fragmentShader.textureCombiner[i].rgbScale = 1;
fragmentShader.textureCombiner[i].alphaScale = 1;
}
fragmentOperation.depth.isTestEnabled = true;
fragmentOperation.depth.testFunction = OTestFunction.lessOrEqual;
fragmentOperation.depth.isMaskEnabled = true;
}
}
///
/// Type of the value on Meta Data.
///
public enum OMetaDataValueType
{
integer = 0,
single = 1,
utf8String = 2,
utf16String = 3
}
///
/// Meta Data.
/// If type is integer, each value in "values" should be casted to (int).
/// If is type is single, value should be casted to (float).
/// If is utf8String or utf16String, value should be casted to (string).
/// The string codification doesn't matter at this point, but may be useful on exporting.
///
public class OMetaData
{
public string name;
public OMetaDataValueType type;
public List