예제 #1
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);
        }
예제 #2
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);
            }
        }