Пример #1
0
        public void TriangleInitialize()
        {
            Vertex a = new Vertex();
            a.Position = new Vector3(0, 1, 0);
            Vertex b = new Vertex();
            b.Position = new Vector3(-1, 0, 0);
            Vertex c = new Vertex();
            c.Position = new Vector3(1, 0, 0);

            Triangle t = new Triangle(a,b,c);

            Assert.Equal(a, t.P0);
            Assert.Equal(b, t.P1);
            Assert.Equal(c, t.P2);
            Assert.Equal(new Vector3(0, 0, 1), t.Normal);
        }
Пример #2
0
        public void RayTriangleTest()
        {
            Vector3 origin = new Vector3(0, 0, 0);
            Vector3 direction = new Vector3(1, 0, 0);
            Ray r = new Ray(origin, direction);
            Triangle t = new Triangle(
                new Vertex() { Position = new Vector3(2, 1, 0) },
                new Vertex() { Position = new Vector3(2, 0, -1) },
                new Vertex() { Position = new Vector3(2, 0, 1) });

            float time = -1f;
            bool collides = r.CollidesWith(t, ref time);

            Assert.True(collides);
            Assert.Equal(2f, time);

            Ray r2 = new Ray(origin, -direction);

            collides = r2.CollidesWith(t, ref time);
            Assert.False(collides);
            Assert.Equal(-2f, time);
        }
Пример #3
0
        public Vector4 GetColor(Triangle t, Vector3 pos)
        {
            Vector4 c = t.GetColor(pos);
            Vector4 retColor = new Vector4(0, 0, 0, 1);

            Vector3 viewVec = (cameraPosition - pos).Normalized;

            foreach (var light in config.Lights)
            {
                Vector3 lightVec = (light.Location - pos).Normalized;

                Vector4 avg = new Vector4();

                // Calcualte diffuse lighting

                // If this is >0 then the triangle light is somewhere in front of the triangle
                float dot = Vector3.Dot(lightVec, t.Normal);
                if (dot < 0) { dot = 0; }
                Vector4 diffuse = new Vector4(
                    c.X * light.DiffuseColor.X * dot,
                    c.Y * light.DiffuseColor.Y * dot,
                    c.Z * light.DiffuseColor.Z * dot,
                    c.W * light.DiffuseColor.W * dot);

                // Calculate specular lighting
                Vector3 reflected = Vector3.Reflection(lightVec, t.Normal).Normalized;
                dot = Vector3.Dot(reflected, viewVec);

                Vector4 specular = new Vector4(
                    (float)Math.Pow(light.SpecularColor.X * dot, t.GetSpecularCoefficient(pos)),
                    (float)Math.Pow(light.SpecularColor.Y * dot, t.GetSpecularCoefficient(pos)),
                    (float)Math.Pow(light.SpecularColor.Z * dot, t.GetSpecularCoefficient(pos)),
                    (float)Math.Pow(light.SpecularColor.W * dot, t.GetSpecularCoefficient(pos)));

                // Cast a bunch of shadow rays to determine how well lit this point is from the given light source
                for(int i = 0;i < config.ShadowRays; i++)
                {
                    if(!InShadow(pos, light))
                    {
                        // If we are lit then add the diffuse and specular colors
                        avg += diffuse;
                        avg += specular;
                    }
                }

                // Average the color by the number of shadow rays cast.
                avg /= config.ShadowRays;

                retColor.X += light.AmbientColor.X * c.X + avg.X;
                retColor.Y += light.AmbientColor.Y * c.Y + avg.Y;
                retColor.Z += light.AmbientColor.Z * c.Z + avg.Z;

                ScaleColor(ref retColor);
            }

            return retColor;
        }
Пример #4
0
        /// <summary>
        /// Casts a ray and gets the resultant color
        /// </summary>
        /// <param name="r">The ray to cast</param>
        /// <param name="depth">The current depth of the ray into the scene</param>
        /// <param name="sourceTriangle">The source of the ray if it was reflected/refracted</param>
        /// <returns>The resultant color of the ray</returns>
        public Vector4 CastRay(Ray r, int depth = 0, Triangle sourceTriangle = null)
        {
            float closestTime = float.MaxValue;
            Triangle closestTriangle = null;
            Vector3 closestPosition = Vector3.Zero;
            Vector4 returnColor = Vector4.Zero;

            foreach (var t in scene.Triangles)
            {
                float time = float.MaxValue;

                if (r.CollidesWith(t, ref time))
                {
                    if (time < closestTime && time > ProximityTolerance)
                    {
                        closestTime = time;
                        closestTriangle = t;
                        closestPosition = r.PointAtDistance(time);
                    }
                }
            }

            // If we can still cast rays deeper and we collided with an object, then cast more rays
            if (depth < config.MaxRayDepth && closestTriangle != null)
            {
                // TODO: Cast reflection rays

                // TODO: Cast refraction rays

                // TODO: Add the color combinations from reflection and refraction
                returnColor = GetColor(closestTriangle, closestPosition);
            }
            else if (closestTriangle != null)
            {
                returnColor = GetColor(closestTriangle, closestPosition);
            }

            return returnColor;
        }
Пример #5
0
        /// <summary>
        /// Does the conversion
        /// </summary>
        /// <param name="data">The obj data to convert</param>
        /// <returns>The constructed Scene</returns>
        public static Scene Convert(ObjData data)
        {
            Scene s = new Scene();
            Dictionary<string, Material> materials = new Dictionary<string, Material>();
            Dictionary<string, Bitmap> bitmaps = new Dictionary<string, Bitmap>();

            foreach (var mat in data.materials)
            {
                LoadBitmap(mat.AlphaTextureMap, bitmaps);
                LoadBitmap(mat.AmbientTextureMap, bitmaps);
                LoadBitmap(mat.BumpMap, bitmaps);
                LoadBitmap(mat.DiffuseTextureMap, bitmaps);
                LoadBitmap(mat.DisplacementMap, bitmaps);
                LoadBitmap(mat.SpecularCoefficientMap, bitmaps);
                LoadBitmap(mat.SpecularTextureMap, bitmaps);

                Material m = new Material();
                m.AlphaMap = bitmaps[mat.AlphaTextureMap];
                m.AmbientMap = bitmaps[mat.AmbientTextureMap];
                m.BumpMap = bitmaps[mat.AmbientTextureMap];
                m.DiffuseMap = bitmaps[mat.AmbientTextureMap];
                m.DisplacementMap = bitmaps[mat.AmbientTextureMap];
                m.SpecularCoefficientMap = bitmaps[mat.AmbientTextureMap];
                m.SpecularMap = bitmaps[mat.AmbientTextureMap];
                m.Texture = bitmaps[mat.DiffuseTextureMap];

                m.AmbientColor = mat.Ambient;
                m.DiffuseColor = mat.Diffuse;
                m.SpecularCoefficient = mat.SpecularCoefficient;
                m.SpecularColor = mat.Specular;
                m.Transparency = mat.Transparency;
                m.Name = mat.Name;
                materials[m.Name] = m;
            }

            foreach (var f in data.faces)
            {
                Vertex v1 = new Vertex();
                Vertex v2 = new Vertex();
                Vertex v3 = new Vertex();

                v1.Position = data.vertices[f.Vert1.vertex - 1];
                v2.Position = data.vertices[f.Vert2.vertex - 1];
                v3.Position = data.vertices[f.Vert3.vertex - 1];

                v1.Normal = data.normals[f.Vert1.normal - 1];
                v2.Normal = data.normals[f.Vert2.normal - 1];
                v3.Normal = data.normals[f.Vert3.normal - 1];

                // Only set the texture coordinates if they were set
                if (f.Vert1.texCoord > 0 && f.Vert2.texCoord > 0 && f.Vert3.texCoord > 0)
                {
                    v1.TexCoord = data.texCoords[f.Vert1.texCoord - 1];
                    v2.TexCoord = data.texCoords[f.Vert2.texCoord - 1];
                    v3.TexCoord = data.texCoords[f.Vert3.texCoord - 1];
                }

                Triangle t = new Triangle(v1, v2, v3);

                if (!string.IsNullOrEmpty(f.Material))
                {
                    t.Material = materials[f.Material];
                }
                
                s.Triangles.Add(t);
            }
            
            return s;
        }