private float m_rotAngle; // angle of cube rotation #endregion /// <summary> /// We initialize the matrices and the vertices for the wire frame cube /// </summary> public frmHelloCube() { // Create matrices m_modelMatrix = new SLMat4f(); m_viewMatrix = new SLMat4f(); m_projectionMatrix = new SLMat4f(); m_viewportMatrix = new SLMat4f(); // define the 8 vertices of a cube m_v = new SLVec3f[8]; m_v[0] = new SLVec3f(-0.5f, -0.5f, 0.5f); // front lower left m_v[1] = new SLVec3f(0.5f, -0.5f, 0.5f); // front lower right m_v[2] = new SLVec3f(0.5f, 0.5f, 0.5f); // front upper right m_v[3] = new SLVec3f(-0.5f, 0.5f, 0.5f); // front upper left m_v[4] = new SLVec3f(-0.5f, -0.5f, -0.5f); // back lower left m_v[5] = new SLVec3f(0.5f, -0.5f, -0.5f); // back lower right m_v[6] = new SLVec3f(0.5f, 0.5f, -0.5f); // back upper left m_v[7] = new SLVec3f(-0.5f, 0.5f, -0.5f); // back upper right m_camZ = -4; // backwards movement of the camera m_rotAngle = 0; // initial rotation angle // Without double buffering it would flicker this.DoubleBuffered = true; InitializeComponent(); }
private SLVec3f trackBallVec(float x, float y) { SLVec3f vec = new SLVec3f(); float r; if (ClientRectangle.Width < ClientRectangle.Height) { r = (float)(ClientRectangle.Width / 2) * 0.88f; } else { r = (float)(ClientRectangle.Height / 2) * 0.88f; } vec.x = (x - ClientRectangle.Width / 2) / r; vec.y = (y - ClientRectangle.Height / 2) / r * -1; float d2 = vec.x * vec.x + vec.y * vec.y; if (d2 < 1f) { vec.z = (float)Math.Sqrt(1f - d2); } else { vec.z = 0f; vec.Normalize(); } return(vec); }
/// <summary> /// creates new Vertex with all new SLVec3(); /// nColor is not set! /// </summary> public SLVertex() { position = new SLVec3f(); normale = new SLVec3f(); color = new SLVec3f(); posInView = new SLVec3f(); }
/// <summary> /// Initializes a new instance of the <see cref="SLVec4f"/> class using coordinates from a given <see cref="SLVec3f"/> instance. /// </summary> /// <param name="vector">A <see cref="SLVec3f"/> to get the coordinates from.</param> public SLVec4f(SLVec3f vector) { this.x = vector.x; this.y = vector.y; this.z = vector.z; this.w = 1; }
/// <summary> /// Defines the view matrix with an eye position, a look at point and an up vector. /// This method is equivalent to the OpenGL function gluLookAt. /// If Up is a zero vector a default up vector is calculated with a default /// look-right vector (VZ) that lies in the x-z plane. /// </summary> /// <param name="Eye">Eye Vector to the position of the eye (view point)</param> /// <param name="At">At Vector to the target point</param> /// <param name="Up">Up Vector that points from the viewpoint upwards.</param> public void LookAt(SLVec3f Eye, SLVec3f At, SLVec3f Up) { SLVec3f VX, VY, VZ, VT, ZERO; //SLMat3<T> xz(0.0, 0.0, 1.0, // matrix that transforms YZ into a // 0.0, 0.0, 0.0, // vector that is perpendicular to YZ and // -1.0, 0.0, 0.0); // lies in the x-z plane VZ = Eye - At; VZ.Normalize(); VX = new SLVec3f(); ZERO = new SLVec3f(); if (Up == ZERO) { VX.x = VZ.z; VX.y = 0; VX.z = -1 * VZ.x; } else { VX = Up.Cross(VZ); } VY = SLVec3f.CrossProduct(VZ, VX); VX.Normalize(); VY.Normalize(); VZ.Normalize(); VT = -Eye; Set(VX.x, VX.y, VX.z, SLVec3f.DotProduct(VX, VT), VY.x, VY.y, VY.z, SLVec3f.DotProduct(VY, VT), VZ.x, VZ.y, VZ.z, SLVec3f.DotProduct(VZ, VT), 0.0f, 0.0f, 0.0f, 1.0f); }
public SLVertex(float px, float py, float pz, SLVec3f col) { this.position = new SLVec3f(px, py, pz); this.normale = null; this.color = col; this.nColor = col / 255; }
/// <summary> /// number of vertices and indices /// </summary> /// <param name="vSize">vertices</param> /// <param name="iSize">indices</param> public Mesh(int vSize, int iSize) { vertices = new SLVertex[vSize]; indices = new int[iSize]; color = new SLVec3f(); modelMatrix = new SLMat4f(); }
/// <summary> /// Setter for all components at once /// </summary> public void Set(SLVec3f v) { x = v.x; y = v.y; z = v.z; w = 1; }
private bool m_mouseLeftDown; // flag if mouse is down #endregion /// <summary> /// We intialize the matrices the the vertices foth the wireframe cube /// </summary> public frmHelloCube() { InitializeComponent(); // Create matrices m_modelViewMatrix = new SLMat4f(); m_projectionMatrix = new SLMat4f(); m_viewportMatrix = new SLMat4f(); // define the 8 vertices of a cube m_v = new SLVec3f[8]; m_v[0] = new SLVec3f(-0.5f, -0.5f, 0.5f); // front lower left m_v[1] = new SLVec3f(0.5f, -0.5f, 0.5f); // front lower right m_v[2] = new SLVec3f(0.5f, 0.5f, 0.5f); // front upper right m_v[3] = new SLVec3f(-0.5f, 0.5f, 0.5f); // front upper left m_v[4] = new SLVec3f(-0.5f, -0.5f, -0.5f); // back lower left m_v[5] = new SLVec3f(0.5f, -0.5f, -0.5f); // back lower right m_v[6] = new SLVec3f(0.5f, 0.5f, -0.5f); // back upper right m_v[7] = new SLVec3f(-0.5f, 0.5f, -0.5f); // back upper left m_camZ = -2; // backwards movment of the camera m_rotx = 0; m_roty = 0; m_dx = 0; m_dy = 0; m_mouseLeftDown = false; // Without double buffering it would flicker this.DoubleBuffered = true; }
/// <summary> /// Post multiplies a translation matrix defined by the vector t /// </summary> public void Translate(SLVec3f t) { SLMat4f Tr = new SLMat4f(); Tr.Translation(t); Multiply(Tr); }
/// <summary> /// Calculates the cross product of two vectors. /// </summary> /// <param name="u">A <see cref="SLVec3f"/> instance.</param> /// <param name="v">A <see cref="SLVec3f"/> instance.</param> /// <returns>A new <see cref="SLVec3f"/> containing the cross product result.</returns> public static SLVec3f CrossProduct(SLVec3f u, SLVec3f v) { return(new SLVec3f( u.y * v.z - u.z * v.y, u.z * v.x - u.x * v.z, u.x * v.y - u.y * v.x)); }
/// <summary> /// Post multiplies a rotation matrix defined by /// the angle degAng and the rotation axis /// </summary> public void Rotate(float degAng, SLVec3f axis) { SLMat4f R = new SLMat4f(); R.Rotation(degAng, axis); Multiply(R); }
/// <summary> /// diffuses the color relative to its light distance /// </summary> /// <param name="light"></param> /// <returns></returns> public SLVec3f difuse(SLLight light) { float NdL = Math.Max(SLVec3f.DotProduct(this.normale, light.direction), 0); SLVec3f colorD = ((nColor & light.diffuse) * NdL); return(colorD); }
/// <summary> /// Post multiplies a scaling matrix defined by the vector s /// </summary> public void Scale(SLVec3f s) { SLMat4f S = new SLMat4f(); S.Scaling(s); Multiply(S); }
/// <summary> /// Post multiplies the matrix by the vector v and writes it into /// a point p with x and y /// </summary> public void Multiply(SLVec3f v, ref System.Drawing.PointF p) { float W = m[3] * v.x + m[7] * v.y + m[11] * v.z + m[15]; p.X = (m[0] * v.x + m[4] * v.y + m[8] * v.z + m[12]) / W; p.Y = (m[1] * v.x + m[5] * v.y + m[9] * v.z + m[13]) / W; }
/// <summary> /// Post multiplies the matrix by the vector v and returns a vector /// with the additional perspective division. /// </summary> public SLVec3f Multiply(SLVec3f v) { float W = m[3] * v.x + m[7] * v.y + m[11] * v.z + m[15]; return(new SLVec3f((m[0] * v.x + m[4] * v.y + m[8] * v.z + m[12]) / W, (m[1] * v.x + m[5] * v.y + m[9] * v.z + m[13]) / W, (m[2] * v.x + m[6] * v.y + m[10] * v.z + m[14]) / W)); }
/// <summary> /// sets but dosn't create a vertex /// </summary> /// <param name="nVertex">new Vertex values</param> public void Set(SLVertex nVertex) { this.position.Set(nVertex.position); this.normale.Set(nVertex.normale); this.color.Set(nVertex.color); this.nColor = color / 255; this.posInView.Set(nVertex.posInView); }
public SLVertex(float px, float py, float pz, SLVec3f norm, SLVec3f col, SLVec3f pVI) { this.position = new SLVec3f(px, py, pz); this.normale = norm; this.color = col; this.nColor = color / 255; this.posInView = pVI; }
/// <summary> /// create new light with /// diffuse 1 1 1 /// ambient 0,1 0,1 0,1 /// direction 0 0 1 /// mirror 0,8 0,8 0,8 /// </summary> public SLLight() { this.diffuse = new SLVec3f(1, 1, 1); this.ambient = new SLVec3f(0.1f, 0.1f, 0.1f); this.direction = new SLVec3f(0, 0, 1); this.mirror = new SLVec3f(0.8f, 0.8f, 0.8f); isPhong = false; }
public SLVertex(SLVec3f pos, SLVec3f normale, SLVec3f color, SLVec3f pIV) { this.position = pos; this.normale = normale; this.color = color; this.nColor = color / 255; this.posInView = pIV; }
/// <summary> /// Returns a value indicating whether this instance is equal to /// the specified object. /// </summary> /// <param name="obj">An object to compare to this instance.</param> /// <returns>True if <paramref name="obj"/> is a <see cref="SLVec3f"/> and has the same values as this instance; otherwise, False.</returns> public override bool Equals(object obj) { if (obj is SLVec3f) { SLVec3f v = (SLVec3f)obj; return((this.x == v.x) && (this.y == v.y) && (this.z == v.z)); } return(false); }
/// <summary> /// Tests whether two vectors are approximately equal given a tolerance value. /// </summary> /// <param name="v">A <see cref="SLVec3f"/> instance.</param> /// <param name="u">A <see cref="SLVec3f"/> instance.</param> /// <param name="tolerance">The tolerance value used to test approximate equality.</param> /// <returns>True if the two vectors are approximately equal; otherwise, False.</returns> public static bool ApproxEqual(SLVec3f v, SLVec3f u, float tolerance) { return ( (System.Math.Abs(v.x - u.x) <= tolerance) && (System.Math.Abs(v.y - u.y) <= tolerance) && (System.Math.Abs(v.z - u.z) <= tolerance) ); }
/// <summary> /// calculates a new color relative to the light /// </summary> /// <param name="light">relative to this light</param> /// <returns>new color</returns> public SLVec3f colorToLight(SLLight light) { if (light.isPhong) { this.normale.Normalize(); } SLVec3f c = spiegel(light) + difuse(light); return(checkColor(c) * 255); }
/// <summary> /// Defines the view matrix with an eye position, a look at point and an up vector. /// This method is equivalent to the OpenGL function gluLookAt. /// If Up is a zero vector a default up vector is calculated with a default /// look-right vector (VZ) that lies in the x-z plane. /// </summary> /// <param name="eyeX"></param> /// <param name="eyeY"></param> /// <param name="eyeZ"></param> /// <param name="atX"></param> /// <param name="atY"></param> /// <param name="atZ"></param> /// <param name="upX"></param> /// <param name="upY"></param> /// <param name="upZ"></param> public void LookAt(float eyeX, float eyeY, float eyeZ, float atX, float atY, float atZ, float upX, float upY, float upZ) { SLVec3f eye = new SLVec3f(eyeX, eyeY, eyeZ); SLVec3f at = new SLVec3f(atX, atY, atZ); SLVec3f up = new SLVec3f(upX, upY, upZ); LookAt(eye, at, up); }
/// <summary> /// calculates mirror effect from normale relative to the light /// </summary> /// <param name="light"></param> /// <returns></returns> public SLVec3f spiegel(SLLight light) { SLVec3f R = 2 * (SLVec3f.DotProduct(light.direction, this.normale)) * this.normale - light.direction; SLVec3f E = -(this.posInView); E.Normalize(); float RsE = (float)Math.Pow(Math.Max(SLVec3f.DotProduct(R, E), 0), 5); return((light.mirror) * RsE); }
/// <summary> /// The forms paint routine where all drawing happens. /// </summary> private void frmHelloCube_Paint(object sender, PaintEventArgs e) { // start with identity every frame m_viewMatrix.Identity(); // view transform: move the coordinate system away from the camera m_viewMatrix.Translate(0, 0, m_camZ); // model transform: rotate the coordinate system increasingly m_modelMatrix.Identity(); //m_modelMatrix.Translate(1, 0, 0); m_modelMatrix.Rotate(m_rotAngle += 0.05f, 0, 1, 0); m_modelMatrix.Scale(2, 2, 2); // build combined matrix out of viewport, projection & modelview matrix SLMat4f m = new SLMat4f(); m.Multiply(m_viewportMatrix); m.Multiply(m_projectionMatrix); m.Multiply(m_viewMatrix); m.Multiply(m_modelMatrix); // transform all vertices into screen space (x & y in pixels and z as the depth) SLVec3f[] v2 = new SLVec3f[8]; for (int i = 0; i < m_v.Length; ++i) { v2[i] = m.Multiply(m_v[i]); } Graphics g = e.Graphics; g.SmoothingMode = SmoothingMode.AntiAlias; // draw front square g.DrawLine(Pens.Red, v2[0].x, v2[0].y, v2[1].x, v2[1].y); g.DrawLine(Pens.Red, v2[1].x, v2[1].y, v2[2].x, v2[2].y); g.DrawLine(Pens.Red, v2[2].x, v2[2].y, v2[3].x, v2[3].y); g.DrawLine(Pens.Red, v2[3].x, v2[3].y, v2[0].x, v2[0].y); // draw back square g.DrawLine(Pens.Green, v2[4].x, v2[4].y, v2[5].x, v2[5].y); g.DrawLine(Pens.Green, v2[5].x, v2[5].y, v2[6].x, v2[6].y); g.DrawLine(Pens.Green, v2[6].x, v2[6].y, v2[7].x, v2[7].y); g.DrawLine(Pens.Green, v2[7].x, v2[7].y, v2[4].x, v2[4].y); // draw from front corners to the back corners g.DrawLine(Pens.Blue, v2[0].x, v2[0].y, v2[4].x, v2[4].y); g.DrawLine(Pens.Blue, v2[1].x, v2[1].y, v2[5].x, v2[5].y); g.DrawLine(Pens.Blue, v2[2].x, v2[2].y, v2[6].x, v2[6].y); g.DrawLine(Pens.Blue, v2[3].x, v2[3].y, v2[7].x, v2[7].y); // Tell the system that the window should be repaint again this.Invalidate(); }
/// <summary> /// Retrieves the camera vectors eye, at and up if this matrix would be a view matrix /// </summary> /// <param name="Eye"></param> /// <param name="At"></param> /// <param name="Up"></param> public void GetLookAt(ref SLVec3f Eye, ref SLVec3f At, ref SLVec3f Up) { SLMat4f invRot = new SLMat4f(this); SLVec3f translation = new SLVec3f(m[12], m[13], m[14]); invRot.m[12] = 0; invRot.m[13] = 0; invRot.m[14] = 0; invRot.Transpose(); Eye.Set(invRot.Multiply(-translation)); // vector to the eye Up.Set(m[1], m[5], m[9]); // normalized look up vector At.Set(-m[2], -m[6], -m[10]); // normalized look at vector }
/// <summary> /// Sets the minimum values of this and the passed vector v /// </summary> public void SetMin(SLVec3f v) { if (v.x < x) { x = v.x; } if (v.y < y) { y = v.y; } if (v.z < z) { z = v.z; } }
/// <summary> /// Sets the maximum values of this and the passed vector v /// </summary> public void SetMax(SLVec3f v) { if (v.x > x) { x = v.x; } if (v.y > y) { y = v.y; } if (v.z > z) { z = v.z; } }
/// <summary> /// Calls DrawPolygon for the vertecies with the same indices /// backface culling calculations /// </summary> /// <param name="v">vertecies</param> /// <param name="index">indecies</param> /// <param name="cam">camera for backfaceculling</param> /// <param name="bmp">bitmap to draw on</param> private void drawVertices(List <SLVertex> v, int[] index, SLVec3f cam, BmpG bmp) { for (int i = 0; i < index.Length; i += 3) { if (backfaceCulling(v[index[i]], v[index[i + 1]], v[index[i + 2]], cam)) { bmp.DrawPolygon(v[index[i]], v[index[i + 1]], v[index[i + 2]]); } } }