Beispiel #1
0
        public static void ComputeNormals <V>(this Mesh <V> mesh) where V : struct, INormalVertex <V>
        {
            if (mesh.Topology != Topology.Triangles)
            {
                return;
            }

            float3[] normals = new float3[mesh.Vertices.Length];

            for (int i = 0; i < mesh.Indices.Length / 3; i++)
            {
                float3 p0 = mesh.Vertices[mesh.Indices[i * 3 + 0]].Position;
                float3 p1 = mesh.Vertices[mesh.Indices[i * 3 + 1]].Position;
                float3 p2 = mesh.Vertices[mesh.Indices[i * 3 + 2]].Position;

                // Compute the normal of the triangle.
                float3 N = cross(p1 - p0, p2 - p0);

                // Add the normal to the vertices involved
                normals[mesh.Indices[i * 3 + 0]] += N;
                normals[mesh.Indices[i * 3 + 1]] += N;
                normals[mesh.Indices[i * 3 + 2]] += N;
            }

            // Update per-vertex normal using normal accumulation normalized.
            for (int i = 0; i < mesh.Vertices.Length; i++)
            {
                mesh.Vertices[i].Normal = normalize(normals[i]);
            }
        }
Beispiel #2
0
        /// <summary>
        /// Welds different vertices with positions close to each other using an epsilon decimation.
        /// </summary>
        public static Mesh <V> Weld <V>(this Mesh <V> mesh, float epsilon = 0.0001f) where V : struct, IVertex <V>
        {
            // Method using decimation...
            // TODO: Implement other methods

            Dictionary <int3, int> uniqueVertices = new Dictionary <int3, int>();

            int[]    mappedVertices = new int[mesh.Vertices.Length];
            List <V> newVertices    = new List <V>();

            for (int i = 0; i < mesh.Vertices.Length; i++)
            {
                V      vertex = mesh.Vertices[i];
                float3 p      = vertex.Position;
                int3   cell   = (int3)(p / epsilon); // convert vertex position in a discrete cell.
                if (!uniqueVertices.ContainsKey(cell))
                {
                    uniqueVertices.Add(cell, newVertices.Count);
                    newVertices.Add(vertex);
                }

                mappedVertices[i] = uniqueVertices[cell];
            }

            int[] newIndices = new int[mesh.Indices.Length];
            for (int i = 0; i < mesh.Indices.Length; i++)
            {
                newIndices[i] = mappedVertices[mesh.Indices[i]];
            }

            return(new Mesh <V>(newVertices.ToArray(), newIndices, mesh.Topology));
        }
Beispiel #3
0
        public static (float4x4, float4x4) GetViewAndProjection(Texture2D texture, float3 cameraPosition, float3 target)
        {
            // View and projection matrices
            var viewMatrix       = Transforms.LookAtLH(cameraPosition, target, float3(0, 1, 0));
            var projectionMatrix =
                Transforms.PerspectiveFovLH(pi_over_4, texture.Height / (float)texture.Width, 0.01f, 20);

            return(viewMatrix, projectionMatrix);
        }
Beispiel #4
0
 static float3 EvalBezier(float3[] control, float t)
 {
     // DeCasteljau
     if (control.Length == 1)
     {
         return(control[0]); // stop condition
     }
     float3[] nestedPoints = new float3[control.Length - 1];
     for (int i = 0; i < nestedPoints.Length; i++)
     {
         nestedPoints[i] = lerp(control[i], control[i + 1], t);
     }
     return(EvalBezier(nestedPoints, t));
 }
Beispiel #5
0
        static void LitRaycast(Texture2D texture)
        {
            // Scene Setup
            float3 CameraPosition = float3(3, 2f, 4);
            float3 LightPosition  = float3(3, 5, -2);

            // View and projection matrices
            float4x4 viewMatrix       = Transforms.LookAtLH(CameraPosition, float3(0, 1, 0), float3(0, 1, 0));
            float4x4 projectionMatrix =
                Transforms.PerspectiveFovLH(pi_over_4, texture.Height / (float)texture.Width, 0.01f, 20);

            Scene <PositionNormal> scene = new Scene <PositionNormal>();

            CreateScene(scene);

            // Raycaster to trace rays and check for shadow rays.
            Raytracer <ShadowRayPayload, PositionNormal> shadower = new Raytracer <ShadowRayPayload, PositionNormal>();

            shadower.OnAnyHit += delegate(IRaycastContext context, PositionNormal attribute,
                                          ref ShadowRayPayload payload)
            {
                // If any object is found in ray-path to the light, the ray is shadowed.
                payload.Shadowed = true;
                // No neccessary to continue checking other objects
                return(HitResult.Stop);
            };

            // Raycaster to trace rays and lit closest surfaces
            Raytracer <RayPayload, PositionNormal> raycaster = new Raytracer <RayPayload, PositionNormal>();

            raycaster.OnClosestHit +=
                delegate(IRaycastContext context, PositionNormal attribute, ref RayPayload payload)
            {
                // Move geometry attribute to world space
                attribute = attribute.Transform(context.FromGeometryToWorld);

                float3 V             = normalize(CameraPosition - attribute.Position);
                float3 L             = normalize(LightPosition - attribute.Position);
                float  lambertFactor = max(0, dot(attribute.Normal, L));

                // Check ray to light...
                ShadowRayPayload shadow = new ShadowRayPayload();
                shadower.Trace(scene,
                               RayDescription.FromTo(
                                   attribute.Position +
                                   attribute.Normal * 0.001f, // Move an epsilon away from the surface to avoid self-shadowing
                                   LightPosition), ref shadow);

                payload.Color = shadow.Shadowed ? float3(0, 0, 0) : float3(1, 1, 1) * lambertFactor;
            };
            raycaster.OnMiss += delegate(IRaycastContext context, ref RayPayload payload)
            {
                payload.Color = float3(0, 0, 1); // Blue, as the sky.
            };

            // Render all points of the screen
            for (int px = 0; px < texture.Width; px++)
            {
                for (int py = 0; py < texture.Height; py++)
                {
                    RayDescription ray = RayDescription.FromScreen(px + 0.5f, py + 0.5f, texture.Width, texture.Height,
                                                                   inverse(viewMatrix), inverse(projectionMatrix), 0, 1000);

                    RayPayload coloring = new RayPayload();

                    raycaster.Trace(scene, ray, ref coloring);

                    texture.Write(px, py, float4(coloring.Color, 1));
                }
            }
        }
Beispiel #6
0
 public static Mesh <V> Revolution(int slices, int stacks, Func <float, float3> g, float3 axis)
 {
     return(Generative(slices, stacks, g, (v, t) => mul(float4(v, 1), Transforms.Rotate(t * 2 * pi, axis)).xyz));
 }
Beispiel #7
0
 public static Mesh <V> Extrude(int slices, int stacks, Func <float, float3> g, float3 direction)
 {
     return(Generative(slices, stacks, g, (v, t) => v + direction * t));
 }
Beispiel #8
0
 public float Distance(float3 pto, out float3 closest)
 {
     return(GTools.distanceP2L(pto, A, B, out closest));
 }
Beispiel #9
0
 public float Distance(float3 pto)
 {
     return(Distance(pto, out float3 _));
 }
Beispiel #10
0
 public Node(int _i, int _j, float3 _pos)
 {
     i   = _i;
     j   = _j;
     pos = _pos;
 }
Beispiel #11
0
 /// <summary>
 /// Creates a line given by two positions in space
 /// </summary>
 public Line3D(float3 a, float3 b)
 {
     A = a;
     B = b;
 }
Beispiel #12
0
 public void UpdateTranslation(float3 source)
 {
     Transform.TranslationVector = Transform.Position - source;
 }
Beispiel #13
0
 public float3 random3(float3 min, float3 max)
 {
     return(random3() * (max - min) + min);
 }
Beispiel #14
0
 public float3 gauss3(float3 mu, float3 sigma)
 {
     return(gauss3() * sigma + mu);
 }
Beispiel #15
0
        /// <summary>
        /// Random uniform direction in a Hemisphere
        /// </summary>
        public float3 randomHSDirection(float3 N)
        {
            float NdotD;

            return(randomHSDirection(N, out NdotD));
        }
Beispiel #16
0
 /// <summary>
 /// Creates a line given by two positions in space
 /// </summary>
 public Line3D(float3 a, float3 b)
 {
     this.A = a;
     this.B = b;
 }