public static mat4x4 LookAtRH(vec3 position, vec3 target, vec3 normal) { vec3 zaxis = (position - target).Normalized; vec3 xaxis = vec3.cross(normal, zaxis).Normalized; vec3 yaxis = vec3.cross(zaxis, xaxis); return new mat4x4( xaxis.X, yaxis.X, zaxis.X, 0, xaxis.Y, yaxis.Y, zaxis.Y, 0, xaxis.Z, yaxis.Z, zaxis.Z, 0, -vec3.dot(xaxis, position), -vec3.dot(yaxis, position), -vec3.dot(zaxis, position), 1 ); }
public static mat4x4 Rotation(float radians, vec3 axis) { //se lleva el eje que se quiere rotar al eje de las X, se rota el eje de las X y se vira para atras mat4x4 t = I4; float alpha = (float)Math.Atan2(axis.Z, axis.X); t = t * RotationY(-alpha); float beta = (float)Math.Atan2(axis.Y, axis.X); t = t * RotationZ(-beta); return t.Inverse * RotationX(radians) * t; }
private static vec2 SphereTextureCoordenates(vec3 position) { return new vec2(position.X / 2 + 0.5f, position.Y); }
private static vec2 PlaneTextureCoordenates(vec3 position) { return new vec2(position.X + 0.5f, position.Z + 0.5f); }
private static vec2 DiskTextureCoordenates(vec3 position) { return new vec2(position.X / 2 + 0.5f, position.Z / 2 + 0.5f); }
private static vec2 CylinderTextureCoordenates(vec3 position) { //tapa superior if (position.Y.AproxEqual(1) || position.Y.AproxEqual(0)) return DiskTextureCoordenates(position); return new vec2(position.X / 2 + 0.5f, position.Y); }
public static vec2 TextureCoordenates(this Model model, vec3 position) { switch (model) { case Model.Cube: return CubeTextureCoordenates(position); case Model.Disk: return DiskTextureCoordenates(position); case Model.Sphere: return SphereTextureCoordenates(position); case Model.Cylinder: return CylinderTextureCoordenates(position); case Model.Cone: return ConeTextureCoordenates(position); case Model.Plane: return PlaneTextureCoordenates(position); default: throw new NotImplementedException(); } }
public static Ray FromDirection(vec3 position, vec3 direction) { return new Ray(position, direction.Normalized); }
public vec4(vec3 v, float w) : this(v.X, v.Y, v.Z, w) { }
//modificado public LightSource(vec3 position, vec4 intensity, ModelGraphic modelGraphicLight) { Position = position; Intensity = intensity; ModelGraphic = modelGraphicLight; }
public static vec3 normalize(vec3 v) { float length = v.Length; if (length == 0) throw new InvalidOperationException(); return new vec3(v.X / length, v.Y / length, v.Z / length); }
public static float dot(vec3 v1, vec3 v2) { return v1.X * v2.X + v1.Y * v2.Y + v1.Z * v2.Z; }
public static vec3 cross(vec3 v1, vec3 v2) { return new vec3( v1.Y * v2.Z - v1.Z * v2.Y, v1.Z * v2.X - v1.X * v2.Z, v1.X * v2.Y - v1.Y * v2.X); }
public static Graphic Rotated(this Graphic graphic, float radians, vec3 axis) { return new TransformedGraphic(graphic, Matrices.Rotation(radians, axis)); }
private static vec2 ConeTextureCoordenates(vec3 position) { return DiskTextureCoordenates(position); }
private Ray(vec3 from, vec3 direction) { this.From = from; this.Direction = direction; }
private static vec2 CubeTextureCoordenates(vec3 position) { // Front Intersection if (position.Z.AproxEqual(0)) return new vec2(position.X, position.Y); // Back Intersection if (position.Z.AproxEqual(1)) return new vec2(1 - position.X, position.Y); // Left Intersection if (position.X.AproxEqual(0)) return new vec2(1 - position.Z, position.Y); // Right Intersection if (position.X.AproxEqual(1)) return new vec2(position.Z, position.Y); // Top Intersection if (position.Y.AproxEqual(1)) return new vec2(position.X, position.Z); // Bottom Intersection if (position.Y.AproxEqual(0)) return new vec2(position.X, position.Z); throw new Exception("Una de las componentes X,Y,Z tiene que ser aproximadamente 1 o 0}"); }
public static Ray FromTo(vec3 position, vec3 target) { return new Ray(position, (target - position).Normalized); }
/// <summary> /// Crea un rayo que parte del observador y atraviesa un punto en la pantalla. /// </summary> private Ray ConstructRay(int px, int py) { /// Soportada por el momento camaras perspectivas if (Scene.Camera is PerspectiveCamera) { var projectionCamera = Scene.Camera as PerspectiveCamera; /// Determinar el alto y ancho de la pantalla en el mundo. float height = (float)Math.Tan(projectionCamera.FieldOfView/2); float width = height * frameBuffer.Width / frameBuffer.Height; /// Punto de la pantalla en coordenadas de proyeccion vec3 projected = new vec3(width * (px / (float)frameBuffer.Width * 2 - 1), height * (1 - 2 * py / (float)frameBuffer.Height), 0); /// Punto de la pantalla en coordenadas del observador. vec3 viewed = projected + new vec3(0, 0, 1); /// Vectores de la camara. vec3 cameraRight = vec3.cross(projectionCamera.Normal, projectionCamera.Direction).Normalized; vec3 cameraNormal = vec3.cross(projectionCamera.Direction, cameraRight).Normalized; vec3 cameraDirection = projectionCamera.Direction.Normalized; /// Rayo. return Ray.FromDirection(projectionCamera.Position, viewed.X * cameraRight + viewed.Y * cameraNormal + viewed.Z * cameraDirection); } throw new NotSupportedException(); }