示例#1
0
            //FUNC
            public void loadFromObjFileAt(string fileName, double x, double y, double z)
            {
                string[]      file  = System.IO.File.ReadAllLines(fileName);
                List <vect3D> verts = new List <vect3D>();

                // line = typeOfLine + v1 + v2 + v3
                foreach (string line in file)
                {
                    string[] lineValues = line.Split(' ');
                    char     typeOfLine = line[0];
                    //vertex
                    if (typeOfLine == 'v')
                    {
                        vect3D vect = new vect3D(Convert.ToDouble(lineValues[1], System.Globalization.CultureInfo.InvariantCulture) + x,
                                                 Convert.ToDouble(lineValues[2], System.Globalization.CultureInfo.InvariantCulture) + y,
                                                 Convert.ToDouble(lineValues[3], System.Globalization.CultureInfo.InvariantCulture) + z);
                        verts.Add(vect);
                    }
                    //triangle
                    else if (typeOfLine == 'f')
                    {
                        int v1, v2, v3;
                        // - 1 because all of the information in the file start counting from 1
                        v1 = Convert.ToInt32(lineValues[1]) - 1;
                        v2 = Convert.ToInt32(lineValues[2]) - 1;
                        v3 = Convert.ToInt32(lineValues[3]) - 1;
                        tris.Add(new triangle(verts[v1], verts[v2], verts[v3]));
                    }
                }
            }
示例#2
0
 public triangle(vect3D v1, vect3D v2, vect3D v3)
 {
     vect    = new vect3D[3];
     vect[0] = v1;
     vect[1] = v2;
     vect[2] = v3;
 }
示例#3
0
            public vect3D CrossProduct(vect3D vect)
            {
                vect3D v = new vect3D();

                v.x = this.y * vect.z - this.z * vect.y;
                v.y = this.z * vect.x - this.x * vect.z;
                v.z = this.x * vect.y - this.y * vect.x;
                return(v);
            }
示例#4
0
            public static vect3D operator *(matrix4x4 m, vect3D v)
            {
                vect3D res = new vect3D();

                res.x = v.x * m.m[0, 0] + v.y * m.m[1, 0] + v.z * m.m[2, 0] + v.w * m.m[3, 0];
                res.y = v.x * m.m[0, 1] + v.y * m.m[1, 1] + v.z * m.m[2, 1] + v.w * m.m[3, 1];
                res.z = v.x * m.m[0, 2] + v.y * m.m[1, 2] + v.z * m.m[2, 2] + v.w * m.m[3, 2];
                res.w = v.x * m.m[0, 3] + v.y * m.m[1, 3] + v.z * m.m[2, 3] + v.w * m.m[3, 3];
                return(res);
            }
示例#5
0
 public MainWindow()
 {
     vCamera = new vect3D(0, 0, 0);
     InitializeComponent();
     initializeMatrix();
     initializeObjects();
     System.Windows.Threading.DispatcherTimer timer = new System.Windows.Threading.DispatcherTimer();
     timer.Tick    += new EventHandler(timerTick);
     timer.Interval = new TimeSpan(0, 0, 0, 0, 1);
     timer.Start();
     canvas.Focus();
 }
示例#6
0
        protected override void OnKeyDown(KeyEventArgs e)
        {
            switch (e.Key)
            {
            //Forward
            case Key.Up:
                vCamera = vCamera + (vLookDir * 1.001);
                break;

            //Left
            case Key.Left:
                vCamera.x -= 1.0;
                break;

            //Right
            case Key.Right:
                vCamera.x += 1.0;
                break;

            //Back
            case Key.Down:
                vCamera = vCamera - (vLookDir * 1.001);
                break;

            // rotate up
            case Key.W:
                fXaw += 0.05;
                break;

            // rotate down
            case Key.S:
                fXaw -= 0.05;
                break;

            // turn left
            case Key.A:
                fYaw += 0.05;
                break;

            // turn right
            case Key.D:
                fYaw -= 0.05;
                break;
            }
            base.OnKeyDown(e);
        }
示例#7
0
        //FUNC
        matrix4x4 matrixPointAt(vect3D pos, vect3D target, vect3D up)
        {
            vect3D newForward = target - pos;

            newForward.Normalize();
            // Calculate new Up direction
            vect3D a     = newForward * up.DotProduct(newForward);
            vect3D newUp = up - a;

            newUp.Normalize();
            // New Right direction is easy, its just cross product
            vect3D newRight = newUp.CrossProduct(newForward);
            // Construct Dimensioning and Translation Matrix
            matrix4x4 matrix = new matrix4x4();

            matrix.m[0, 0] = newRight.x; matrix.m[0, 1] = newRight.y; matrix.m[0, 2] = newRight.z; matrix.m[0, 3] = 0.0f;
            matrix.m[1, 0] = newUp.x; matrix.m[1, 1] = newUp.y; matrix.m[1, 2] = newUp.z; matrix.m[1, 3] = 0.0f;
            matrix.m[2, 0] = newForward.x; matrix.m[2, 1] = newForward.y; matrix.m[2, 2] = newForward.z; matrix.m[2, 3] = 0.0f;
            matrix.m[3, 0] = pos.x; matrix.m[3, 1] = pos.y; matrix.m[3, 2] = pos.z; matrix.m[3, 3] = 1.0f;
            return(matrix);
        }
示例#8
0
 public double DotProduct(vect3D vect)
 {
     return(this.x * vect.x + this.y * vect.y + this.z * vect.z);
 }
示例#9
0
        private void timerTick(object sender, EventArgs e)
        {
            canvas.Children.Clear();

            double deltaX = 0.2;
            double fDelta = 2 * Math.PI / (4 * r / deltaX);

            fTheta += fDelta;
            matrix4x4 matRotZ = getMatrixRotationZ(0);
            matrix4x4 matRotX = getMatrixRotationX(0);
            matrix4x4 matRotY = getMatrixRotationY(fTheta);

            if (Math.Abs(x) >= r)
            {
                isHalfRotated = !isHalfRotated;
            }
            x += isHalfRotated ? deltaX : -deltaX;


            double z = isHalfRotated ? -Math.Sqrt(r * r - x * x) : Math.Sqrt(r * r - x * x);

            z += 4 * r;


            matrix4x4 matTrans = getMatrixTranslation(x, 1, z);;


            // all the transformations that we need to do in this matrix
            matrix4x4 matWorld = createUnitMatrix();

            matWorld = matRotZ * matRotX * matRotY;
            matWorld = matWorld * matTrans;

            //camera
            vect3D    vUp          = new vect3D(0, 1, 0);
            vect3D    vTarget      = new vect3D(0, 0, 1);
            matrix4x4 matCameraRot = getMatrixRotationY(fYaw) * getMatrixRotationX(fXaw);

            vLookDir = matCameraRot * vTarget;
            vTarget  = vCamera + vLookDir;
            matrix4x4 matCamera = matrixPointAt(vCamera, vTarget, vUp);
            matrix4x4 matView   = matrixQuickInverse(matCamera);

            List <triangle> trianglesToRaster = new List <triangle>();

            foreach (triangle tri in meshCube.tris)
            {
                triangle triProjected   = new triangle();
                triangle triTransformed = new triangle();
                triangle triViewed      = new triangle();
                triTransformed.vect[0] = matWorld * tri.vect[0];
                triTransformed.vect[1] = matWorld * tri.vect[1];
                triTransformed.vect[2] = matWorld * tri.vect[2];

                vect3D normal = new vect3D();
                vect3D line1  = new vect3D();
                vect3D line2  = new vect3D();

                line1 = triTransformed.vect[1] - triTransformed.vect[0];
                line2 = triTransformed.vect[2] - triTransformed.vect[0];

                normal = line1.CrossProduct(line2);
                normal.Normalize();

                //projecting

                // объект виден если угол между нормалью к нему и нашей камерой меньше 90 градусов
                // будем проверять это с помощью скалярного произведения векторов
                // скалярное произведение векторов угол между которыми > 90 градусов будет < 0
                if (normal.DotProduct(triTransformed.vect[0] - vCamera) < 0.0)
                {
                    // illumination (all illumination cooming from direction, not from the point)
                    // свет тем ярче чем меньше угол между нормалью поверхности с направлением света
                    vect3D lightDirection = new vect3D(-5.0, -5.0, -5.0);
                    lightDirection.Normalize();

                    double dp = normal.DotProduct(lightDirection);
                    triProjected.luminosity   = dp;
                    triTransformed.luminosity = dp;

                    triViewed.vect[0] = matView * triTransformed.vect[0];
                    triViewed.vect[1] = matView * triTransformed.vect[1];
                    triViewed.vect[2] = matView * triTransformed.vect[2];

                    triProjected.vect[0] = matProj * triViewed.vect[0];
                    triProjected.vect[1] = matProj * triViewed.vect[1];
                    triProjected.vect[2] = matProj * triViewed.vect[2];

                    triProjected.vect[0] = triProjected.vect[0] / triProjected.vect[0].w;
                    triProjected.vect[1] = triProjected.vect[1] / triProjected.vect[1].w;
                    triProjected.vect[2] = triProjected.vect[2] / triProjected.vect[2].w;

                    //offset into visible mormalized space
                    vect3D vOffsetView = new vect3D(1, 1, 0);

                    triProjected.vect[0] = triProjected.vect[0] + vOffsetView;
                    triProjected.vect[1] = triProjected.vect[1] + vOffsetView;
                    triProjected.vect[2] = triProjected.vect[2] + vOffsetView;

                    triProjected.vect[0].x *= canvas.Width / 2.0;
                    triProjected.vect[0].y *= canvas.Height / 2.0;
                    triProjected.vect[1].x *= canvas.Width / 2.0;
                    triProjected.vect[1].y *= canvas.Height / 2.0;
                    triProjected.vect[2].x *= canvas.Width / 2.0;
                    triProjected.vect[2].y *= canvas.Height / 2.0;

                    trianglesToRaster.Add(triProjected);
                }
            }
            // Sort triangles from back to front
            try {
                trianglesToRaster.Sort();
            }
            catch (Exception ex)
            {
            }
            foreach (triangle t in trianglesToRaster)
            {
                DrawTriangle(t, true, true);
            }
        }