//transformuje vektor (x,y,z,1) matici m public Vector3 Transform(Matrix44 m) { double w = x*m.M[3,0] + y*m.M[3,1] + z*m.M[3,2] + m.M[3,3]; return new Vector3((x*m.M[0,0] + y*m.M[0,1] + z*m.M[0,2] + m.M[0,3])/w, (x*m.M[1,0] + y*m.M[1,1] + z*m.M[1,2] + m.M[1,3])/w, (x*m.M[2,0] + y*m.M[2,1] + z*m.M[2,2] + m.M[2,3])/w ); }
public Projection(double angle,double aspect,double n,double f) { double tan = Math.Tan(angle/2); double cotan = 1/tan; width = tan*n*2/aspect; height= tan*n*2; znear = n; zfar = f; matrix = new Matrix44(new double [,] {{cotan/aspect,0,0,0}, {0,cotan,0,0}, {0,0,(f+n)/(n-f),(2*f*n)/(n-f)}, {0,0,-1,0}}); }
//vynasobi matici pm1 matici pm2 a vrati vysledek jako novou matici public static Matrix44 Multiply(Matrix44 pm1,Matrix44 pm2) { int i; int j; Matrix44 newmatrix = new Matrix44(); for (i = 0; i < 4; i++) { for (j = 0; j < 4; j++) { newmatrix.m[i,j] = pm1.M[i,0]*pm2.M[0,j] + pm1.M[i,1]*pm2.M[1,j] + pm1.M[i,2]*pm2.M[2,j] + pm1.M[i,3]*pm2.M[3,j]; } } return newmatrix; }
private double[,] zbuffer; //pamet hloubky #endregion Fields #region Constructors //nastavi promenne na defaultni hodnoty. //parametrem bitmap se predava odkaz na bitmapu do ktere se bude kreslit public Soft3DScreen(Int32[,] bitmap) { screen = bitmap; screenHeight = bitmap.GetLength(1); screenWidth = bitmap.GetLength(0); zbuffer = new double[screenWidth, screenHeight]; for(int i = 0;i<screenWidth;i++) for(int j = 0;j<screenHeight;j++) zbuffer[i,j] = 1;//inicializace z bufferu na max hodnotu projection = new Projection(Math.PI/4,(double)screenWidth/(double)screenHeight, 2.4,50);//nastaveni projekce,zorny uhel je 45 stupnu viewport = new Viewport(2,2, screenWidth,screenHeight); byte[] white = {255,255,255,255}; color = BitConverter.ToInt32(white, 0); viewMatrix=Matrix44.GetIdentityMatrix(); }
//otoci okolo osy x o uhel angle (v radianech) public void RotateX(double angle) { Matrix44 matrix = new Matrix44(new double[,] {{1,0,0,0},{0,Math.Cos(angle),-Math.Sin(angle),0}, {0,Math.Sin(angle),Math.Cos(angle),0},{0,0,0,1}}); m = Multiply(this,matrix).M; }
//otoci okolo osy axis o uhel angle,axis musi byt normalizovany vektor public void RotateAxisAngle(Vector3 axis,double angle) { double x = axis.X; double y = axis.Y; double z = axis.Z; Matrix44 matrix = new Matrix44(new double[,] {{1 + (1-Math.Cos(angle))*(x*x-1), -z*Math.Sin(angle)+(1-Math.Cos(angle))*x*y, y*Math.Sin(angle)+(1-Math.Cos(angle))*x*z, 0}, {z*Math.Sin(angle)+(1-Math.Cos(angle))*x*y, 1 + (1-Math.Cos(angle))*(y*y-1), -x*Math.Sin(angle)+(1-Math.Cos(angle))*y*z, 0}, {-y*Math.Sin(angle)+(1-Math.Cos(angle))*x*z, x*Math.Sin(angle)+(1-Math.Cos(angle))*y*z, 1 + (1-Math.Cos(angle))*(z*z-1), 0}, {0,0,0,1}}); m = Multiply(this,matrix).M; }
//posune ve smeru vektoru (tx,ty,tz) public void Translate(double tx,double ty,double tz) { Matrix44 matrix = new Matrix44(new double[,] {{1,0,0,tx},{0,1,0,ty},{0,0,1,tz},{0,0,0,1}}); m = Multiply(this,matrix).M; }
//provede zmenu, pro kazdou osu je zmena specifikovana jednim parametrem public void Scale(double scalex,double scaley,double scalez) { Matrix44 matrix = new Matrix44(new double[,] {{scalex,0,0,0},{0,scaley,0,0},{0,0,scalez,0},{0,0,0,1}}); m = Multiply(this,matrix).M; }
//vytvori model ze seznamu trojuhelniku public Model3D(List<TexturedTriangle> ptriangles,Matrix44 m) { matrix = m; triangles = ptriangles.ToArray(); }