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 values; public OMetaData() { values = new List(); } } /// /// Culling mode of the Model. /// public enum OModelCullingMode { dynamic = 0, always = 1, never = 2 } /// /// Model data, such as the meshes, materials and skeleton. /// public class OModel { public string name; public uint layerId; public List mesh; public List skeleton; public List material; public List userData; public OMatrix transform; public OVector3 minVector, maxVector; public int verticesCount { get { int count = 0; foreach (RenderBase.OMesh obj in mesh) count += obj.vertices.Count; //TODO Ommit duplicate verts return count; } } public OModel() { mesh = new List(); skeleton = new List(); material = new List(); userData = new List(); transform = new OMatrix(); minVector = new OVector3(); maxVector = new OVector3(); } } /// /// Format of the texture used on the PICA200. /// public enum OTextureFormat { rgba8 = 0, rgb8 = 1, rgba5551 = 2, rgb565 = 3, rgba4 = 4, la8 = 5, hilo8 = 6, l8 = 7, a8 = 8, la4 = 9, l4 = 0xa, a4 = 0xb, etc1 = 0xc, etc1a4 = 0xd, dontCare } /// /// Texture, contains the texture name and Bitmap image. /// public class OTexture { public Bitmap texture; public string name; /// /// Creates a new Texture. /// /// The texture, size must be a power of 2 /// Texture name public OTexture(Bitmap _texture, string _name) { texture = new Bitmap(_texture); _texture.Dispose(); name = _name; } } /// /// Sampler of a LookUp Table, contains the data. /// public class OLookUpTableSampler { public string name; public float[] table; public OLookUpTableSampler() { table = new float[256]; } } /// /// 1-D LookUp table. /// public class OLookUpTable { public string name; public List sampler; public OLookUpTable() { sampler = new List(); } } /// /// Type of a light. /// public enum OLightType { directional = 0, point = 1, spot = 2 } /// /// Where and how the light data is used. /// public enum OLightUse { hemiSphere = 0, vertex = 1, fragment = 2, ambient = 3 } /// /// Represents a light source. /// public class OLight { public string name; public OVector3 transformScale; public OVector3 transformRotate; public OVector3 transformTranslate; public Color ambient; public Color diffuse; public Color specular0; public Color specular1; public OVector3 direction; public float attenuationStart; public float attenuationEnd; public bool isLightEnabled; public bool isTwoSideDiffuse; public bool isDistanceAttenuationEnabled; public OLightType lightType; public OLightUse lightUse; //Vertex public float distanceAttenuationConstant; public float distanceAttenuationLinear; public float distanceAttenuationQuadratic; public float spotExponent; public float spotCutoffAngle; //HemiSphere public Color groundColor; public Color skyColor; public float lerpFactor; public OFragmentSampler angleSampler; public OFragmentSampler distanceSampler; } /// /// View mode of a camera. /// public enum OCameraView { aimTarget = 0, lookAtTarget = 1, rotate = 2 } /// /// Projection mode of a camera. /// public enum OCameraProjection { perspective = 0, orthogonal = 1 } /// /// Represents a camera on a scene. /// public class OCamera { public string name; public OVector3 transformScale; public OVector3 transformRotate; public OVector3 transformTranslate; public OVector3 target; public OVector3 rotation; public OVector3 upVector; public float twist; public OCameraView view; public OCameraProjection projection; public float zNear, zFar; public float fieldOfViewY; public float height; public float aspectRatio; public bool isInheritingTargetRotate; public bool isInheritingTargetTranslate; public bool isInheritingUpRotate; } /// /// Fog update method. /// public enum OFogUpdater { linear = 0, exponent = 1, exponentSquare = 2 } /// /// Represents a fog on a scene. /// public class OFog { public string name; public OVector3 transformScale; public OVector3 transformRotate; public OVector3 transformTranslate; public Color fogColor; public OFogUpdater fogUpdater; public float minFogDepth, maxFogDepth, fogDensity; public bool isZFlip; public bool isAttenuateDistance; } /// /// Repeat method of a animation. /// public enum ORepeatMethod { none = 0, repeat = 1, mirror = 2, relativeRepeat = 3 } /// /// Value used on each Frame element of the animation /// public class OAnimationKeyFrame { public float frame; public float value; public float inSlope; public float outSlope; public bool bValue; /// /// Creates a new Key Frame. /// This Key Frame can be used on Hermite Interpolation. /// /// The point value /// The input slope /// The output slope /// The frame number public OAnimationKeyFrame(float _value, float _inSlope, float _outSlope, float _frame) { value = _value; inSlope = _inSlope; outSlope = _outSlope; frame = _frame; } /// /// Creates a new Key Frame. /// This Key Frame can be used on Linear or Step interpolation. /// /// The point value /// The frame number public OAnimationKeyFrame(float _value, float _frame) { value = _value; frame = _frame; } /// /// Creates a new Key Frame. /// This Key Frame can be used on Boolean values animation. /// /// The point value /// The frame number public OAnimationKeyFrame(bool _value, float _frame) { bValue = _value; frame = _frame; } /// /// Creates a new Key Frame. /// public OAnimationKeyFrame() { } public override string ToString() { return string.Format("Frame:{0}; Value (float):{1}; Value (boolean):{2}; InSlope:{3}; OutSlope:{4}", frame, value, bValue, inSlope, outSlope); } } /// /// Interpolation mode of the animation. /// Step = Jump from key frames, like the big pointer of a clock. /// Linear = Linear interpolation between values. /// Hermite = Hermite interpolation between values, have two slope values too. /// public enum OInterpolationMode { step = 0, linear = 1, hermite = 2 } /// /// Key frame of an animation. /// public class OAnimationKeyFrameGroup { public List keyFrames; public OInterpolationMode interpolation; public float startFrame, endFrame; public bool exists; public bool defaultValue; public ORepeatMethod preRepeat; public ORepeatMethod postRepeat; public OAnimationKeyFrameGroup() { keyFrames = new List(); } } /// /// Normal frame of an animation. /// public class OAnimationFrame { public List vector; public float startFrame, endFrame; public bool exists; public ORepeatMethod preRepeat; public ORepeatMethod postRepeat; public OAnimationFrame() { vector = new List(); } } /// /// Type of an animation segment. /// public enum OSegmentType { single = 0, vector2 = 2, vector3 = 3, transform = 4, rgbaColor = 5, integer = 6, transformQuaternion = 7, boolean = 8, transformMatrix = 9 } /// /// Type of the segment quantization. /// public enum OSegmentQuantization { hermite128 = 0, hermite64 = 1, hermite48 = 2, unifiedHermite96 = 3, unifiedHermite48 = 4, unifiedHermite32 = 5, stepLinear64 = 6, stepLinear32 = 7 } /// /// Bone of an Skeletal Animation. /// public class OSkeletalAnimationBone { public string name; public OAnimationKeyFrameGroup scaleX, scaleY, scaleZ; public OAnimationKeyFrameGroup rotationX, rotationY, rotationZ; public OAnimationKeyFrameGroup translationX, translationY, translationZ; public bool isAxisAngle; public OAnimationFrame rotationQuaternion; public OAnimationFrame translation; public OAnimationFrame scale; public bool isFrameFormat; public List transform; public bool isFullBakedFormat; public OSkeletalAnimationBone() { scaleX = new OAnimationKeyFrameGroup(); scaleY = new OAnimationKeyFrameGroup(); scaleZ = new OAnimationKeyFrameGroup(); rotationX = new OAnimationKeyFrameGroup(); rotationY = new OAnimationKeyFrameGroup(); rotationZ = new OAnimationKeyFrameGroup(); translationX = new OAnimationKeyFrameGroup(); translationY = new OAnimationKeyFrameGroup(); translationZ = new OAnimationKeyFrameGroup(); rotationQuaternion = new OAnimationFrame(); translation = new OAnimationFrame(); scale = new OAnimationFrame(); transform = new List(); } } /// /// Animation loop mode. /// public enum OLoopMode { oneTime = 0, loop = 1 } /// /// Base animation class, all animations should inherit from this class. /// public class OAnimationBase { public virtual string name { get; set; } public virtual float frameSize { get; set; } public virtual OLoopMode loopMode { get; set; } } /// /// Base class of list with animation. /// It is used as a generic way to access all animation, casting each list element as appropriate. /// public class OAnimationListBase { public List list; public OAnimationListBase() { list = new List(); } } /// /// Represents a Skeletal Animation. /// public class OSkeletalAnimation : OAnimationBase { public override string name { get; set; } public override float frameSize { get; set; } public override OLoopMode loopMode { get; set; } public List bone; public List userData; public OSkeletalAnimation() { bone = new List(); userData = new List(); } } /// /// Model data affected by the given Material Animation. /// public enum OMaterialAnimationType { constant0 = 1, constant1 = 2, constant2 = 3, constant3 = 4, constant4 = 5, constant5 = 6, emission = 7, ambient = 8, diffuse = 9, specular0 = 0xa, specular1 = 0xb, borderColorMapper0 = 0xc, textureMapper0 = 0xd, borderColorMapper1 = 0xe, textureMapper1 = 0xf, borderColorMapper2 = 0x10, textureMapper2 = 0x11, blendColor = 0x12, scaleCoordinator0 = 0x13, rotateCoordinator0 = 0x14, translateCoordinator0 = 0x15, scaleCoordinator1 = 0x16, rotateCoordinator1 = 0x17, translateCoordinator1 = 0x18, scaleCoordinator2 = 0x19, rotateCoordinator2 = 0x1a, translateCoordinator2 = 0x1b } /// /// Data of the Material Animation. /// public class OMaterialAnimationData { public string name; public OMaterialAnimationType type; public List frameList; public OMaterialAnimationData() { frameList = new List(); } } /// /// Represents a Material Animation. /// public class OMaterialAnimation : OAnimationBase { public override string name { get; set; } public override float frameSize { get; set; } public override OLoopMode loopMode { get; set; } public List data; public List textureName; public OMaterialAnimation() { data = new List(); textureName = new List(); } } /// /// Data used on visibility animation. /// public class OVisibilityAnimationData { public string name; public OAnimationKeyFrameGroup visibilityList; public OVisibilityAnimationData() { visibilityList = new OAnimationKeyFrameGroup(); } } /// /// Represents visibility animation of a mesh. /// public class OVisibilityAnimation : OAnimationBase { public override string name { get; set; } public override float frameSize { get; set; } public override OLoopMode loopMode { get; set; } public List data; public OVisibilityAnimation() { data = new List(); } } /// /// Light data affected by the Light Animation. /// public enum OLightAnimationType { transform = 0x1c, ambient = 0x1d, diffuse = 0x1e, specular0 = 0x1f, specular1 = 0x20, direction = 0x21, distanceAttenuationStart = 0x22, distanceAttenuationEnd = 0x23, isLightEnabled = 0x24 } /// /// Data of the light animation. /// public class OLightAnimationData { public string name; public OLightAnimationType type; public List frameList; public OLightAnimationData() { frameList = new List(); } } /// /// Represents a Light Animation. /// public class OLightAnimation : OAnimationBase { public override string name { get; set; } public override float frameSize { get; set; } public override OLoopMode loopMode { get; set; } public OLightType lightType; public OLightUse lightUse; public List data; public OLightAnimation() { data = new List(); } } /// /// Camera data affected by the Camera Animation. /// public enum OCameraAnimationType { transform = 5, vuTargetPosition = 6, vuTwist = 7, vuUpwardVector = 8, vuViewRotate = 9, puNear = 0xa, puFar = 0xb, puFovy = 0xc, puAspectRatio = 0xd, puHeight = 0xe } /// /// Camera animation data. /// public class OCameraAnimationData { public string name; public OCameraAnimationType type; public List frameList; public OCameraAnimationData() { frameList = new List(); } } /// /// Represents a Camera Animation. /// public class OCameraAnimation : OAnimationBase { public override string name { get; set; } public override float frameSize { get; set; } public override OLoopMode loopMode { get; set; } public OCameraView viewMode; public OCameraProjection projectionMode; public List data; public OCameraAnimation() { data = new List(); } } /// /// Data used on Fog Animation. /// public class OFogAnimationData { public string name; public List colorList; public OFogAnimationData() { colorList = new List(); } } /// /// Represents a Fog Animation. /// public class OFogAnimation : OAnimationBase { public override string name { get; set; } public override float frameSize { get; set; } public override OLoopMode loopMode { get; set; } public List data; public OFogAnimation() { data = new List(); } } /// /// Reference of a scene element. /// public struct OSceneReference { public uint slotIndex; public string name; } /// /// Represents a Scene Environment. /// It references other data used to compose a scene. /// public class OScene { public string name; public List cameras; public List lights; public List fogs; public OScene() { cameras = new List(); lights = new List(); fogs = new List(); } } /// /// Model Group, contains everything related to 3-D rendering. /// public class OModelGroup { public List model; public List texture; public List lookUpTable; public List light; public List camera; public List fog; public OAnimationListBase skeletalAnimation; public OAnimationListBase materialAnimation; public OAnimationListBase visibilityAnimation; public OAnimationListBase lightAnimation; public OAnimationListBase cameraAnimation; public OAnimationListBase fogAnimation; public List scene; public OModelGroup() { model = new List(); texture = new List(); lookUpTable = new List(); light = new List(); camera = new List(); fog = new List(); skeletalAnimation = new OAnimationListBase(); materialAnimation = new OAnimationListBase(); visibilityAnimation = new OAnimationListBase(); lightAnimation = new OAnimationListBase(); cameraAnimation = new OAnimationListBase(); fogAnimation = new OAnimationListBase(); scene = new List(); } /// /// Merges all the content of a ModelGroup with this ModelGroup. /// /// The contents to be merged public void merge(OModelGroup data) { model.AddRange(data.model); texture.AddRange(data.texture); lookUpTable.AddRange(data.lookUpTable); light.AddRange(data.light); camera.AddRange(data.camera); fog.AddRange(data.fog); skeletalAnimation.list.AddRange(data.skeletalAnimation.list); materialAnimation.list.AddRange(data.materialAnimation.list); visibilityAnimation.list.AddRange(data.visibilityAnimation.list); lightAnimation.list.AddRange(data.lightAnimation.list); cameraAnimation.list.AddRange(data.cameraAnimation.list); fogAnimation.list.AddRange(data.fogAnimation.list); scene.AddRange(data.scene); } } } }