public Model(string name = "unnamed", string path = "unnamed", Vector traslation = null, Vector rotation = null, Vector scaling = null) : base(name) { this.Path = path; triangleList = new List<Triangle>(); SetUpDelegates(); }
public Sphere(string name = "", Vector center = null, float Radius = 1) : base(translation: center) { this.Radius = Radius; this.Wireframe = false; SetUpDelegates(); }
public static float[] GetVector3Array(Vector v) { float[] array = new float[3]; array[0] = v.x; array[1] = v.y; array[2] = v.z; return array; }
public Figure(string name = "", Vector translation = null, Vector rotation = null, Vector scaling = null) { this.Name = name; this.Traslation = translation != null ? translation : new Vector(); this.Rotation = rotation != null ? rotation : new Vector(); this.Scaling = scaling != null ? scaling : new Vector(1, 1, 1); buttonDictionary = new Dictionary<string, Button>(); }
public static XElement GetXYZElement(string name, Vector data) { XElement element = new XElement(name); element.SetAttributeValue("x", data.x); element.SetAttributeValue("y", data.y); element.SetAttributeValue("z", data.z); return element; }
public static XElement GetRGBElement(string name, Vector data) { XElement element = new XElement(name); element.SetAttributeValue("red", data.x); element.SetAttributeValue("green", data.y); element.SetAttributeValue("blue", data.z); return element; }
public void EditPropertyByOffset(string property, Vector offset) { Vector mask = new Vector(1,1,1); switch (property) { case "Position": EditPosition(Traslation + offset, mask); break; case "Rotation": EditRotation(Rotation + 10*offset, mask); break; case "Scale": EditScaling(Scaling + offset, mask); break; } }
public Cube(Vector position, Vector rotation, Vector scaling, float size, Vector color = null, String textureName = "") : base(translation: position, rotation: rotation, scaling: scaling) { if (textureName != "") LoadTexture(textureName); // Creamos los vértices ocupando nuestros conocimientos binarios vertices.Add(new Vector(size / 2, size / 2, size / 2)); // 0 vertices.Add(new Vector(size / 2, size / 2, -size / 2)); // 1 vertices.Add(new Vector(size / 2, -size / 2, size / 2)); // 2 vertices.Add(new Vector(size / 2, -size / 2, -size / 2)); // 3 vertices.Add(new Vector(-size / 2, size / 2, size / 2)); // 4 vertices.Add(new Vector(-size / 2, size / 2, -size / 2)); // 5 vertices.Add(new Vector(-size / 2, -size / 2, size / 2)); // 6 vertices.Add(new Vector(-size / 2, -size / 2, -size / 2)); // 7 /** * Creamos los índices para cada tríangulo, según cara * Agregamos además las normales a cada cara. El último índice indica la normal. * * Hagan el dibujo del cubo y vean porque se ocupan estos índices y normales **/ indices.Add(new int[] { 0, 1, 2, 0 }); indices.Add(new int[] { 3, 1, 2, 0 }); normals.Add(new Vector(1, 0, 0)); indices.Add(new int[] { 7, 5, 3, 1 }); indices.Add(new int[] { 1, 5, 3, 1 }); normals.Add(new Vector(0, 0, -1)); indices.Add(new int[] { 4, 5, 0, 2 }); indices.Add(new int[] { 1, 5, 0, 2 }); normals.Add(new Vector(0, 1, 0)); indices.Add(new int[] { 6, 7, 4, 3 }); indices.Add(new int[] { 5, 7, 4, 3 }); normals.Add(new Vector(-1, 0, 0)); indices.Add(new int[] { 6, 7, 2, 4 }); indices.Add(new int[] { 3, 7, 2, 4 }); normals.Add(new Vector(0, -1, 0)); indices.Add(new int[] { 6, 4, 2, 5 }); indices.Add(new int[] { 0, 4, 2, 5 }); normals.Add(new Vector(0, 0, 1)); this.color = color != null ? color : new Vector(); }
// El botón ignora las propiedades offsetX y offsetY ya que se las dan en el Draw // Es un desorden más o menos ya que hice el error de poner presentación en el modelo // (MVC fue creado para evitar precisamente eso. Es uno de los TODO) public Button(string text, int width, int height, int inputCount, List<string> propertyList, bool numberButton = true) : base(width, height, 0, 0, 2) { this.numberButton = numberButton; this.Name = text; this.inputCount = inputCount; this.inputIndex = 0; this.currentInput = new Vector(); this.propertyList = propertyList; outerColor = new Vector(0.2, 0.2, 0.2); innerColor = new Vector(0.9, 0.9, 0.9); selectedColor = new Vector(0.7, 0.7, 0.7); // Indica si termino de parsear el input COMPLETED = false; selected = false; }
/// <summary> /// Inicializa la cámara /// </summary> public Camera(double fov, double near, double far, Vector target = null, float radius = 10.0f, double alfa = 0, double beta = 0) { this.FOV = fov; this.NearClip = near; this.FarClip = far; //this.Position = position != null ? position : new Vector(); this.Target = target != null ? target : new Vector(); //this.Up = up != null ? up : new Vector(0, 1, 0); // Apunta hacia arriba por default // Obtenemos los datos de la representación angular this.Radius = radius; this.Alfa = alfa; this.Beta = beta; cameraMode = CameraMode.Free; // Ahora calculamos la posición y el Up CalculatePosition(); }
/// <summary> /// Dot product of a 3-dimensional vector /// </summary> /// <param name="v1"></param> /// <param name="v2"></param> /// <returns></returns> public static float Dot3(Vector v1, Vector v2) { return v1.x * v2.x + v1.y * v2.y + v1.z * v2.z; }
public static Vector Cross3(Vector v1, Vector v2) { Vector crossVec = new Vector(); crossVec.x = v1.y * v2.z - v2.y * v1.z; crossVec.y = v2.x * v1.z - v1.x * v2.z; crossVec.z = v1.x * v2.y - v2.x * v1.y; crossVec.w = 0.0f; return crossVec; }
public void CalculatePosition() { float z = Target.z + Radius * (float)Math.Cos(BetaRad) * (float)Math.Cos(AlfaRad); float x = Target.x - Radius * (float)Math.Cos(BetaRad) * (float)Math.Sin(AlfaRad); float y = Target.y + Radius * (float)Math.Sin(BetaRad); // En OpenGL y representa lo que entendemos por altura Position = new Vector(x, y, z); /** * Ahora tenemos que calcular el Up. Esto no es tán simple si la cámara ha rotado bastante. * Lo que hacemos es calcular el vector "Right", ocupando la proyección de la posición relativa en el * plano XZ y el vector y canónico (0,1,0). Con este vector Right, podemos hacer el producto * cruz entre la posición de la cámara y él para finalmente encontrar el dichoso Up vector **/ Vector relPosition = Position - Target; // TIP: Recuerden la regla de la mano derecha /** * Tenemos un problema cuando la cámara mira exactamente desde el eje Y. * Ahí ocurre que la proyección al eje XZ es el vector (0,0,0), lo que nos deja un UP indefinido. * Lo que hacemos ahí es calcular el Up en base al ángulo Alfa que teníamos anteriormente. * * PD: Escoger que Alfa es válido para estos casos no es trivial ya que hay que elegir el correcto * tal que el movimiento haga sentido al escoger la vista desde el eje Y. **/ //int betaComparison = (int)Beta; // Hacemos esto porque la comparación precisa con double no funciona bien... if (Beta != 90 && Beta != 270) { Right = Vector.Cross3(new Vector(relPosition.x, 0, relPosition.z), new Vector(0, 1, 0)); this.Up = Vector.Cross3(Right, Position).Normalize3(); // El dichoso Up } else { // Queremos el up contrario a la posición desde donde veniamos double alfaUp = Alfa; //if (alfaUp > 360) alfaUp -= 360; this.Up = new Vector(Math.Sin(Math.PI*alfaUp/180), 0, -Math.Cos(Math.PI*alfaUp/180)); Right = Vector.Cross3(relPosition, Up).Normalize3(); } }
public Teapot(Vector position, float size) : base(translation: position) { this.Size = size; }
public Vector GetTexturePixelColor(int x, int y) { if (TextureImage == null) return null; Color c = TextureImage.GetPixel(x, y); Vector color = new Vector(c.R / 255.0f, c.G / 255.0f, c.B / 255.0f, c.A / 255.0f); return color; }
/// <summary> /// Carga modelos OBJ. Si bien se importa bien el modelo, no hay funcionalidades implementadas aún /// para manejar de manera efectiva un modelo. /// </summary> /// <param name="xmlScene">El XML de la escena</param> public bool LoadObjModel(string fileName) { string name = "OBJ-Load: " + fileName + " "; int nameIndex = 0; string fileNameFull = "Scene/" + fileName + ".obj"; if (System.IO.File.Exists(fileNameFull)) { using (System.IO.StreamReader sr = System.IO.File.OpenText(fileNameFull)) { //create model container Model model = new Model(fileName, fileName+".xml"); Dictionary<Vector, List<Vector>> vertexToNormalMap = new Dictionary<Vector, List<Vector>>(); //Map to associate face normals to vertexes List<Vector> vertexBuffer = new List<Vector>(); // Allocate memory for the verteces List<Vector> Faces_Triangles = new List<Vector>(); // Allocate memory for the triangles List<Vector> normals = new List<Vector>(); // Allocate memory for the normals List<Vector> textCoordsBuffer = new List<Vector>(); // Allocate memory for the text coordinates string line; while ((line = sr.ReadLine()) != null) { if (line.Length < 1) { continue; } if (line.StartsWith("vt")) // The first characters are vt: on this line is a Textcoord stored. { string cleanLine = line.Remove(0, 2).Trim(); string[] splittedLine = cleanLine.Split(' '); float x = Math.Max(0, Math.Min(1, float.Parse(splittedLine[0]))); float y = Math.Max(0, Math.Min(1, float.Parse(splittedLine[1]))); float z = Math.Max(0, Math.Min(1, float.Parse(splittedLine[2]))); Vector texCoords = new Vector(x, y, z); textCoordsBuffer.Add(texCoords); } else if (line.StartsWith("vn")) // The first characters are vn: on this line is a normal stored. { string cleanLine = line.Remove(0, 2).Trim(); string[] splittedLine = cleanLine.Split(' '); float x = float.Parse(splittedLine[0]); float y = float.Parse(splittedLine[1]); float z = float.Parse(splittedLine[2]); Vector normal = new Vector(x, y, z); normals.Add(normal); } else if (line[0] == 'v') // The first character is a v: on this line is a vertex stored. { string cleanLine = line.Remove(0, 1).Trim(); string[] splittedLine = cleanLine.Split(' '); float x = float.Parse(splittedLine[0]); float y = float.Parse(splittedLine[1]); float z = float.Parse(splittedLine[2]); Vector v = new Vector(x, y, z); vertexBuffer.Add(v); vertexToNormalMap.Add(v, new List<Vector>()); } else if (line[0] == 'f') // The first character is a f: on this line is a face. { string cleanLine = line.Remove(0, 1).Trim(); string[] splittedLine = cleanLine.Split(' '); int[] vertexNumber = new int[4]; string[] splittedVertex1Info = splittedLine[0].Split('/'); string[] splittedVertex2Info = splittedLine[1].Split('/'); string[] splittedVertex3Info = splittedLine[2].Split('/'); string[] splittedVertex4Info = null; if (splittedLine.Length > TRIANGLE_FACES) //If the face is a quad, there are 4 vertex splittedVertex4Info = splittedLine[3].Split('/'); //First component of the vertex info is the index of the vertex position vertexNumber[0] = int.Parse(splittedVertex1Info[0].Trim('-')) - 1; // OBJ file starts counting from 1 vertexNumber[1] = int.Parse(splittedVertex2Info[0].Trim('-')) - 1; vertexNumber[2] = int.Parse(splittedVertex3Info[0].Trim('-')) - 1; if (splittedLine.Length > TRIANGLE_FACES) //If the face is a quad, there are 4 vertex vertexNumber[3] = int.Parse(splittedVertex4Info[0].Trim('-')) - 1; //Console.WriteLine("" + vertexNumber[0] + ", " + vertexNumber[1] + ", " + vertexNumber[2] + ", " + vertexNumber[3]); Vector vector1 = vertexBuffer[vertexNumber[0]]; Vector vector2 = vertexBuffer[vertexNumber[1]]; Vector vector3 = vertexBuffer[vertexNumber[2]]; List<Vector> vertexList = new List<Vector>(3); vertexList.Add(vector1); vertexList.Add(vector2); vertexList.Add(vector3); List<Vector> vertexList2 = null; Vector vector4 = null; if (splittedLine.Length > TRIANGLE_FACES) //If the face is a quad, we will create two triangles { vertexList2 = new List<Vector>(3); vector4 = vertexBuffer[vertexNumber[3]]; vertexList2.Add(vector1); vertexList2.Add(vector3); vertexList2.Add(vector4); } List<Vector> textCoordsList = null; List<Vector> textCoordsList2 = null; //If the vertex info has two elements, the second is the texture coords index if (splittedVertex1Info.Length > 1 && splittedVertex2Info.Length > 1 && splittedVertex3Info.Length > 1) { Vector textCoords1 = textCoordsBuffer[int.Parse(splittedVertex1Info[1].Trim('-')) - 1]; Vector textCoords2 = textCoordsBuffer[int.Parse(splittedVertex2Info[1].Trim('-')) - 1]; Vector textCoords3 = textCoordsBuffer[int.Parse(splittedVertex3Info[1].Trim('-')) - 1]; textCoordsList = new List<Vector>(3); textCoordsList.Add(textCoords1); textCoordsList.Add(textCoords2); textCoordsList.Add(textCoords3); if (splittedLine.Length > TRIANGLE_FACES) //If the face is a quad, there are 2 triangles, one tex coord list for each { Vector textCoords4 = textCoordsBuffer[int.Parse(splittedVertex4Info[1].Trim('-')) - 1]; textCoordsList2 = new List<Vector>(3); textCoordsList2.Add(textCoords1); textCoordsList2.Add(textCoords3); textCoordsList2.Add(textCoords4); } } List<Vector> normalList = new List<Vector>(3); List<Vector> normalList2 = new List<Vector>(3); bool useFileNormals = false; // If the normals are given in the file, we wont calculate them //If the vertex info has three elements, the third is the normals index if (splittedVertex1Info.Length > 2 && splittedVertex2Info.Length > 2 && splittedVertex3Info.Length > 2) { Vector n1 = normals[int.Parse(splittedVertex1Info[2].Trim('-')) - 1]; Vector n2 = normals[int.Parse(splittedVertex2Info[2].Trim('-')) - 1]; Vector n3 = normals[int.Parse(splittedVertex3Info[2].Trim('-')) - 1]; normalList.Add(n1); normalList.Add(n2); normalList.Add(n3); if (splittedLine.Length > TRIANGLE_FACES) //If the face is a quad, there are 2 triangles, one tex coord list for each { Vector n4 = textCoordsBuffer[int.Parse(splittedVertex4Info[2].Trim('-')) - 1]; normalList2.Add(n1); normalList2.Add(n3); normalList2.Add(n4); } useFileNormals = true; } else { Vector normal = calculateNormal(vector1, vector2, vector3); vertexToNormalMap[vector1].Add(normal); vertexToNormalMap[vector2].Add(normal); vertexToNormalMap[vector3].Add(normal); if (splittedLine.Length > TRIANGLE_FACES) //If the face is a quad, there are 4 vertex vertexToNormalMap[vector4].Add(normal); normalList.Add(normal); normalList.Add(normal); normalList.Add(normal); normalList2.Add(normal); normalList2.Add(normal); normalList2.Add(normal); } Triangle triangle = new Triangle(name + nameIndex++, vertexList, normalList, textCoordsList); triangle.GenerateNormal = !useFileNormals; model.addTriangle(triangle); if (splittedLine.Length > TRIANGLE_FACES) //If the face is a quad, we will create two triangles { triangle = new Triangle(name + nameIndex++, vertexList2, normalList2, textCoordsList2); triangle.GenerateNormal = !useFileNormals; model.addTriangle(triangle); } } } //We will calculate the normals per vertex, using the normals of all faces surroiunding each one foreach(Triangle t in model.triangleList) { if (t.GenerateNormal) { t.NormalList.Clear(); foreach (Vector v in t.VertexList) { List<Vector> normalsPerVertex = vertexToNormalMap[v]; //List of every normal associated to this vertex Vector finalNormal = new Vector(); foreach (Vector n in normalsPerVertex) finalNormal += n; finalNormal = finalNormal / normalsPerVertex.Count; finalNormal = finalNormal.Normalize3(); t.NormalList.Add(finalNormal); } } } AddFigure(model); } } else { Console.WriteLine("file not found"); return false; } Console.WriteLine("loaded!"); return true; }
protected void EditScaling(Vector values, Vector mask) { Vector result = new Vector(); for (int i = 0; i < 4; i++) result[i] = mask[i] == 0 ? Scaling[i] : values[i]; this.Scaling = result; }
public static Matrix operator *(Matrix M1, Matrix M2) { Vector v1 = new Vector(M2.M11, M2.M21, M2.M31, M2.M41); Vector v2 = new Vector(M2.M12, M2.M22, M2.M32, M2.M42); Vector v3 = new Vector(M2.M13, M2.M23, M2.M33, M2.M43); Vector v4 = new Vector(M2.M14, M2.M24, M2.M34, M2.M44); Vector v1Result = M1 * v1; Vector v2Result = M1 * v2; Vector v3Result = M1 * v3; Vector v4Result = M1 * v4; Matrix result = new Matrix(); result.M11 = v1Result.x; result.M12 = v2Result.x; result.M13 = v3Result.x; result.M14 = v4Result.x; result.M21 = v1Result.y; result.M22 = v2Result.y; result.M23 = v3Result.y; result.M24 = v4Result.y; result.M31 = v1Result.z; result.M32 = v2Result.z; result.M33 = v3Result.z; result.M34 = v4Result.z; result.M41 = v1Result.w; result.M42 = v2Result.w; result.M43 = v3Result.w; result.M44 = v4Result.w; return result; }
protected void EditRadius(Vector values, Vector mask) { Radius = mask[0] == 0 ? Radius : values[0]; }
public static Vector operator *(Matrix M, Vector v) { float x = M.M11 * v.x + M.M12 * v.y + M.M13 * v.z + M.M14 * v.w; float y = M.M21 * v.x + M.M22 * v.y + M.M23 * v.z + M.M24 * v.w; float z = M.M31 * v.x + M.M32 * v.y + M.M33 * v.z + M.M34 * v.w; float w = M.M41 * v.x + M.M42 * v.y + M.M43 * v.z + M.M44 * v.w; Vector transformedVector = new Vector(x, y, z, w); return transformedVector; }
public Material(string name) { this.Name = name; Specular = new Vector(); Diffuse = new Vector(); }
public override void Update(int value) { // Rotamos el cubo en el eje z Rotation += new Vector(-0.3f, 1f, 2f); float x = 0f; if (Rotation.x < 0) x = 360f; else if (Rotation.x > 360) x = -360f; float y = 0f; if (Rotation.y < 0) y = 360f; else if (Rotation.y > 360) y = -360f; float z = 0f; if (Rotation.z < 0) z = 360f; else if (Rotation.z > 360) z = -360f; Rotation += new Vector(x, y, z); }
protected override void CallbackMethod(string property, Object values) { // Sacamos la máscara // Por default una máscara que no hace nada Vector mask = new Vector(); if(values is Vector) mask = InputMask((Vector)values); switch (property) { case "Position": EditPosition((Vector)values, mask); break; case "Rotation": EditRotation((Vector)values, mask); break; case "Scale": EditScaling((Vector)values, mask); break; case "Vertex 0": EditVertex0((Vector)values, mask); break; case "Vertex 1": EditVertex1((Vector)values, mask); break; case "Vertex 2": EditVertex2((Vector)values, mask); break; default: base.CallbackMethod(property, values); break; } }
protected Vector calculateNormal( Vector coord1, Vector coord2, Vector coord3 ) { /* calculate Vector1 and Vector2 */ /* float[] va = new float[3], vb = new float[3], vr = new float[3]; double val; va[0] = coord1[0] - coord2[0]; va[1] = coord1[1] - coord2[1]; va[2] = coord1[2] - coord2[2]; vb[0] = coord1[0] - coord3[0]; vb[1] = coord1[1] - coord3[1]; vb[2] = coord1[2] - coord3[2]; /* cross product * / vr[0] = va[1] * vb[2] - vb[1] * va[2]; vr[1] = vb[0] * va[2] - va[0] * vb[2]; vr[2] = va[0] * vb[1] - vb[0] * va[1]; /* normalization factor * / val = Math.Sqrt( vr[0]*vr[0] + vr[1]*vr[1] + vr[2]*vr[2] ); Vector norm = new Vector(vr[0]/val, vr[1]/val, vr[2]/val); return norm;*/ Vector va = coord1 - coord2; Vector vb = coord1 - coord3; return Vector.Cross3(va, vb).Normalize3(); }
protected void EditRotation(Vector values, Vector mask) { Vector result = new Vector(); for (int i = 0; i < 4; i++) result[i] = mask[i] == 0 ? Rotation[i] : values[i]; this.Rotation = result; }
/// <summary> /// Método que carga los datos de la cámara desde la especificación XML /// /// La carga aún no está perfecta, ya que ignora el dato position, ya que lo calcula /// internamente usando coordenadas esféricas (ver implementación de la cámara). /// Por mientras la cámara va a tener que ser ajustada manualmente. /// /// </summary> /// <param name="xmlScene">La escena cargada desde XML</param> protected void LoadCamera(XElement xmlScene = null) { if (xmlScene != null && xmlScene.Elements("camera").Any()) { // Cargamos la primera cámara que encontramos en el archivo XElement xmlCamera = xmlScene.Elements("camera").First(); // Cargamos los datos a la cámara // (Me dió lata hacer uso de algún patrón de diseño más bonito) SceneCamera.FOV = LoadFloat(xmlCamera, "fieldOfView"); SceneCamera.NearClip = LoadFloat(xmlCamera, "nearClip"); SceneCamera.FarClip = LoadFloat(xmlCamera, "farClip"); //SceneCamera.Position = LoadXYZFloat(xmlCamera.Elements("position").First()); Vector Target = LoadXYZFloat(xmlCamera.Elements("target").First()); Vector Position = LoadXYZFloat(xmlCamera.Elements("position").First()); SceneCamera.Target = Target; SceneCamera.Radius = (Target - Position).Magnitude3(); SceneCamera.Up = LoadXYZFloat(xmlCamera.Elements("up").First()); // Calculamos la posición a partir de los datos ya especificados SceneCamera.CalculatePosition(); } else { // Cargamos los datos default a la cámara SceneCamera.FOV = 45.0f; SceneCamera.NearClip = 0.1f; SceneCamera.FarClip = 200.0f; Vector Target = new Vector(); SceneCamera.Target = Target; Vector Position = new Vector(25, 0, 0); SceneCamera.Radius = (Target - Position).Magnitude3(); SceneCamera.Up = new Vector(0, 1, 0); // Calculamos la posición a partir de los datos ya especificados SceneCamera.CalculatePosition(); } }
protected void EditVertex2(Vector values, Vector mask) { Vector result = new Vector(); for (int i = 0; i < 4; i++) result[i] = mask[i] == 0 ? VertexList[2][i] : values[i]; this.VertexList[2] = result; }
/// <summary> /// Carga las luces que van a ser utilizadas en la escena /// </summary> /// <param name="xmlScene">La escena en XML</param> private void LoadLights(XElement xmlScene = null) { if (xmlScene != null && xmlScene.Elements("light_list").Any()) { // Obtenemos el elemento con las luces XElement xmlLights = xmlScene.Elements("light_list").First(); foreach (XElement xmlLight in xmlLights.Elements("light")) { Vector position = LoadXYZDouble(xmlLight.Elements("position").First()); Vector color = LoadColor(xmlLight.Elements("color").First()); XElement attenuation = xmlLight.Elements("attenuation").First(); float quadratic = LoadFloat(attenuation, "quadratic"); float linear = LoadFloat(attenuation, "linear"); float constant = LoadFloat(attenuation, "constant"); // Creamos la luz if (SceneLights.Count <= lightLimit) { Light light = new Light(position, diffuse: color, constantAttenuation: new Vector(constant, constant, constant), linearAttenuation: new Vector(linear, linear, linear), quadraticAttenuation: new Vector(quadratic, quadratic, quadratic)); SceneLights.Add(light); } } } else { Vector position = new Vector(0, 5, 0); Vector color = new Vector(1, 1, 1); // Luz blanca float quadratic = 0; float linear = 0; float constant = 1; Light light = new Light(position, diffuse: color, constantAttenuation: new Vector(constant, constant, constant), linearAttenuation: new Vector(linear, linear, linear), quadraticAttenuation: new Vector(quadratic, quadratic, quadratic)); SceneLights.Add(light); } }
public InfoMenu(int width, int height, int offsetX, int offsetY) : base(width, height, offsetX, offsetY, 3) { outerColor = new Vector(0.2, 0.2, 0.2); innerColor = new Vector(0.9, 0.9, 0.9); }
/// <summary> /// Genera una máscara que dice que datos deben tomar el valor original, usando un valor /// predeterminado que funciona como UNDEFINED o UNCHANGED. /// Este valor está definido en la clase Scene. /// </summary> /// <param name="values">Los valores del vector</param> /// <returns>La máscara correspondiente</returns> protected Vector InputMask(Vector values) { Vector result = new Vector(); for (int i = 0; i < 4; i++) result[i] = values[i] == Scene.Scene.UNDEFINED ? 0 : 1; return result; }