Example #1
0
        /// <summary>
        /// Reversed reverse transformation.
        /// </summary>
        public Vec3 ReverseTransform(Vec3 input)
        {
            Vec3   transformedCamera = Transform(_camera);
            Vec3   tempVec           = input.Diff(transformedCamera);
            double l  = tempVec.Norm;
            double dt = Math.Sqrt(l * d);

            tempVec.Normalize();
            tempVec = tempVec.Mult(dt);
            return(tempVec.Sum(transformedCamera));
        }
        /// <summary>
        /// Die Oberflächennormalen werden abgerundet.
        /// </summary>
        protected void CreateSmoothNormales()
        {
            normalesSmooth1 = new Vec3[pData.Width, pData.Height];
            normalesSmooth2 = new Vec3[pData.Width, pData.Height];

            // Normieren
            for (int i = 0; i < pData.Width; i++)
            {
                for (int j = 0; j < pData.Height; j++)
                {
                    PixelInfo pInfo = pData.Points[i, j];
                    if (pInfo != null)
                    {
                        // pInfo.Normal.Normalize();
                        normalesSmooth1[i, j] = pInfo.Normal;
                        normalesSmooth1[i, j].Normalize();
                    }
                }
            }

            Vec3[,] currentSmooth = normalesSmooth1;
            Vec3[,] nextSmooth = normalesSmooth2;
            Vec3[,] tempSmooth;

            int smoothLevel = (int)ParameterDict.Current.GetDouble("Renderer.SmoothNormalLevel");
            for (int currentSmoothLevel = 0; currentSmoothLevel < smoothLevel; currentSmoothLevel++)
            {

                // create nextSmooth
                for (int i = 0; i < pData.Width; i++)
                {
                    for (int j = 0; j < pData.Height; j++)
                    {
                        Vec3 center = null;
                        center = currentSmooth[i, j];
                        PixelInfo pInfo = pData.Points[i, j];
                        // Test ohne smooth-Factor
                        // Nachbarelemente zusammenrechnen
                        Vec3 neighbors = new Vec3();
                        int neighborFound = 0;
                        for (int k = -1; k <= 1; k++)
                        {
                            for (int l = -1; l <= 1; l++)
                            {
                                int posX = i + k;
                                int posY = j + l;
                                if (posX >= 0 && posX < pData.Width && posY >= 0 && posY < pData.Height)
                                {
                                    Vec3 currentNormal = null;
                                    currentNormal = currentSmooth[i + k, j + l];
                                    PixelInfo pInfo2 = pData.Points[i + k, j + l];

                                    if (currentNormal != null)
                                    {
                                        double amount = 1;
                                        if (pInfo != null && pInfo2 != null)
                                        {
                                            double dist = pInfo.Coord.Dist(pInfo2.Coord);

                                            double dGlobal = maxPoint.Dist(minPoint);
                                            dGlobal /= 1500;
                                            if (dist < dGlobal)
                                                amount = 1.0;
                                            else if (dist > dGlobal && dist < 5.0 * dGlobal)
                                                amount = 1.0 - (dGlobal / dist / 5.0);
                                            else
                                                amount = 0;
                                        }

                                        neighbors.Add(currentNormal.Mult(amount));
                                        neighborFound++;
                                    }
                                }
                            }
                        }
                        neighbors.Normalize();
                        if (center != null)
                        {
                            nextSmooth[i, j] = center;
                            if (center != null || neighborFound > 1)
                            {
                                Vec3 center2 = center;
                                center2.Mult(200);
                                neighbors.Add(center2.Mult(4));
                                neighbors.Normalize();
                                nextSmooth[i, j] = neighbors;
                            }
                        }
                        else
                        {
                            if (neighborFound > 4)
                            {
                                nextSmooth[i, j] = neighbors;
                            }
                        }
                    }
                }

                tempSmooth = currentSmooth;
                currentSmooth = nextSmooth;
                nextSmooth = tempSmooth;

            }
        }
        /// <summary>
        /// Liefert die Farbe der Oberfläche entsprechend der Normalen.
        /// </summary>
        /// <param name="normal"></param>
        /// <returns></returns>
        protected virtual Vec3 GetLight(Vec3 normal)
        {
            Vec3 retVal = new Vec3(backColorRed, backColorGreen, backColorBlue);
            if (!useLight)
            {
                return new Vec3(0.5, 0.5, 0.5);
            }
            if (normal == null)
                return retVal;

            double weight_shini = shininessFactor;
            double weight_diffuse = 1 - weight_shini;

            double norm = Math.Sqrt(normal.X * normal.X + normal.Y * normal.Y + normal.Z * normal.Z);
            // Der Winkel ist nun das Skalarprodukt mit (0,-1,0)= Lichtstrahl
            // mit Vergleichsvektor (Beide nachträglich normiert )
            double angle = 0;
            if (norm == 0)
                return retVal;

            Vec3 lightVec = new Vec3(lightRay.X, lightRay.Y, lightRay.Z);
            lightVec.Normalize();
            double norm2 = lightVec.Norm;
            angle = Math.Acos((normal.X * lightVec.X + normal.Y * lightVec.Y + normal.Z * lightVec.Z) / (norm * norm2)) / (Math.PI / 2.0);

            angle = 1 - angle;
            if (angle < 0)
                angle = 0;
            if (angle > 1)
                angle = 1;
            double light = weight_diffuse * angle + weight_shini * Math.Pow(angle, shininess);
            //   double light =(Math.Pow(angle, 128));
            //   double light = angle;
            if (light < 0)
                light = 0;
            if (light > 1)
                light = 1;

            retVal.X = light;
            retVal.Y = light;
            retVal.Z = light;

            return retVal;
        }