Exemplo n.º 1
0
        public override Transform Step(double time, LocationOptions options)
        {
            var dt = (float)(time - _time);
            var v  = _vel * dt + 0.5f * _acc * dt * dt;

            if (Vec3.Dot(v, v) == 0.0)
            {
                return(base.Step(time, options));
            }

            position = _pos + v;

            if (!options.RotationOptions.HasFlag(RotationOptions.AlignToVelocity))
            {
                return(base.Step(time, options));
            }

            v = _vel + _acc * dt;
            v.Normalize();

            var n = new Vector3(local_orientation.v13, local_orientation.v23, local_orientation.v33);
            var u = new Vector3(v.x, v.y, v.z);

            var proj = u - Vector3.Dot(u, n) * n;

            var north = new Vector3(local_orientation.v12, local_orientation.v22, local_orientation.v32);
            var dot   = Vector3.Dot(proj, north);
            var det   = Vector3.Dot(n, Vector3.Cross(north, proj));

            _euler.y = -(float)Math.Atan2(det, dot);

            return(base.Step(time, options));
        }
Exemplo n.º 2
0
        public static NQuaternion GetDeltaQuaternionWithDirectionVectors(NVector3 a, NVector3 b)
        {
            var dot = NVector3.Dot(a, b);

            if (dot < -0.999999)
            {
                var cross = NVector3.Cross(a, b);
                if (cross.Length() < 0.000001)
                {
                    cross = NVector3.Cross(NVector3.UnitY, a);
                }
                cross = NVector3.Normalize(cross);
                return(NQuaternion.CreateFromAxisAngle(cross, Pi));
            }
            else if (dot > 0.999999)
            {
                return(new NQuaternion(0, 0, 0, 1));
            }
            else
            {
                var xyz = NVector3.Cross(a, b);
                var w   = (float)(Math.Sqrt(a.Length() * a.Length() + b.Length() * b.Length()) + dot);
                return(new NQuaternion(xyz.X, xyz.Y, xyz.Z, w));
            }
        }
Exemplo n.º 3
0
        /// <summary>
        /// Find the closest point to the origin.
        /// </summary>
        /// <param name="W">Simplex</param>
        /// <returns>Closest point on simplex to origin.</returns>
        public Vector ClosestPoint(Simplex W)
        {
            Vector d = new Vector();

            if (W.count >= 2)
            {
                d = W.B.MinkowskiPoint - W.A.MinkowskiPoint;
            }

            switch (W.count)
            {
            case 0:
                return(new Vector(0, 0));

            case 1:
                return(W.A.MinkowskiPoint);

            case 2:
                return(W.A.MinkowskiPoint - (((d * W.A.MinkowskiPoint) / (d * d)) * d));

            case 3: {
                Vector3 W1     = new Vector3((float)W.A.MinkowskiPoint.X, (float)W.A.MinkowskiPoint.Y, 0);
                Vector3 W2     = new Vector3((float)W.B.MinkowskiPoint.X, (float)W.B.MinkowskiPoint.Y, 0);
                Vector3 W3     = new Vector3((float)W.C.MinkowskiPoint.X, (float)W.C.MinkowskiPoint.Y, 0);
                Vector3 n      = Vector3.Cross((W2 - W1), (W3 - W1));
                Vector3 result = Vector3.Multiply(((Vector3.Multiply(n, W1)) / (Vector3.Multiply(n, n))), n);
                return(new Vector(result.X, result.Y));
            }
            }
            return(new Vector(0, 0));
        }
        public MeshNormalsFallback(Schema2.Mesh mesh)
        {
            foreach (var srcPrim in mesh.Primitives)
            {
                var accessor = srcPrim.GetVertexAccessor("POSITION");
                if (accessor == null)
                {
                    continue;
                }

                var positions = accessor.AsVector3Array();

                foreach (var srcTri in srcPrim.GetTriangleIndices())
                {
                    var a = positions[srcTri.A];
                    var b = positions[srcTri.B];
                    var c = positions[srcTri.C];
                    var d = XYZ.Cross(b - a, c - a);

                    AddWeightedNormal(a, d);
                    AddWeightedNormal(b, d);
                    AddWeightedNormal(c, d);
                }
            }
        }
Exemplo n.º 5
0
        public override RayCastResult Intersection(Ray ray, float nowbest)
        {
            if (ray.OriginObject == this)
            {
                return(null);
            }
            {
                (bool happened, Float mint) = BoundBox.Intersection(ray);
                if (!happened || mint > nowbest)                   // 未相交 或 当前最小解已不是最优
                {
                    return(null);
                }
            }
            Float    u, v, t_tmp = 0;
            Vector3f pvec = Vector3f.Cross(ray.Direction, e2);             // S1
            Float    det  = Vector3f.Dot(e1, pvec);

            Float    det_inv = 1.0f / det;
            Vector3f tvec    = ray.Origin - v0;          // S

            u = Vector3f.Dot(tvec, pvec) * det_inv;
            if (u < 0 || u > 1)
            {
                return(null);
            }
            Vector3f qvec = Vector3f.Cross(tvec, e1);             // S2

            v = Vector3f.Dot(ray.Direction, qvec) * det_inv;
            if (v < 0 || u + v > 1)
            {
                return(null);
            }
            t_tmp = Vector3f.Dot(e2, qvec) * det_inv;
            if (t_tmp < 0)
            {
                return(null);
            }

            RayCastResult result = new RayCastResult();

            result.distance      = t_tmp;
            result.obj           = this;
            result.coords        = ray.Origin + t_tmp * ray.Direction;
            result.uv            = new Vector2f(u, v);
            result.normal        = Tools.UVMerge(u, v, n0, n1, n2);
            result.internalPoint = (Vector3f.Dot(result.normal, ray.Direction) > 0);
            if (result.internalPoint)
            {
                result.normal = -result.normal;
            }
            return(result);
        }
Exemplo n.º 6
0
        /**
         * Gets the face normal
         *
         * @return face normal
         */
        public Vector3d getNormal()
        {
            Point3d  p1 = v1.getPosition();
            Point3d  p2 = v2.getPosition();
            Point3d  p3 = v3.getPosition();
            Vector3d xy, xz, normal;

            xy = new Vector3d(p2.X - p1.X, p2.Y - p1.Y, p2.Z - p1.Z);
            xz = new Vector3d(p3.X - p1.X, p3.Y - p1.Y, p3.Z - p1.Z);

            /*normal = new Vector3d();
             * normal.cross(xy, xz);
             * normal.normalize();*/

            normal = Vector3d.Normalize(Vector3d.Cross(xy, xz));

            return(normal);
        }
Exemplo n.º 7
0
        private static IFlowField GenerateFlowField()
        {
            var f = new SimpleFlowField(50, 1, 50, new Vector3(25, 0.5f, 25));

            //Start random
            f.Randomize(1);

            //Swirl around center
            //Half the field is a swirl (basically just concentric circles) while the other half has a slight bias to spiral inwards towards the center
            f.Func(pos => Vector3.Lerp(pos / 5, Vector3.Normalize(Vector3.Cross(pos, Vector3.UnitY)), pos.X > 0.5f ? 0.75f : 0.9f), 0.85f);

            //Keep it flat on the plane
            f.ClampXZ();

            //Clean NaN values
            f.Clean();

            return(f);
        }
Exemplo n.º 8
0
        //----------------------------------CONSTRUCTORS---------------------------------//

        /**
         * Constructor for a line. The line created is the intersection between two planes
         *
         * @param face1 face representing one of the planes
         * @param face2 face representing one of the planes
         */
        public Line(Face face1, Face face2)
        {
            Vector3d normalFace1 = face1.getNormal();
            Vector3d normalFace2 = face2.getNormal();

            //direction: cross product of the faces normals
            //direction = new Vector3d();
            //direction.cross(normalFace1, normalFace2);

            direction = Vector3d.Cross(normalFace1, normalFace2);

            //if direction lenght is not zero (the planes aren't parallel )...
            if (!(direction.Length() < TOL))
            {
                //getting a line point, zero is set to a coordinate whose direction
                //component isn't zero (line intersecting its origin plan)
                point = new Point3d();
                float d1 = -(normalFace1.X * face1.v1.X + normalFace1.Y * face1.v1.Y + normalFace1.Z * face1.v1.Z);
                float d2 = -(normalFace2.X * face2.v1.X + normalFace2.Y * face2.v1.Y + normalFace2.Z * face2.v1.Z);
                if (Math.Abs(direction.X) > TOL)
                {
                    point.X = 0;
                    point.Y = (d2 * normalFace1.Z - d1 * normalFace2.Z) / direction.X;
                    point.Z = (d1 * normalFace2.Y - d2 * normalFace1.Y) / direction.X;
                }
                else if (Math.Abs(direction.Y) > TOL)
                {
                    point.X = (d1 * normalFace2.Z - d2 * normalFace1.Z) / direction.Y;
                    point.Y = 0;
                    point.Z = (d2 * normalFace1.X - d1 * normalFace2.X) / direction.Y;
                }
                else
                {
                    point.X = (d2 * normalFace1.Y - d1 * normalFace2.Y) / direction.Z;
                    point.Y = (d1 * normalFace2.X - d2 * normalFace1.X) / direction.Z;
                    point.Z = 0;
                }
            }

            direction = Vector3d.Normalize(direction);
        }
Exemplo n.º 9
0
        public override void Initialize()
        {
            Vector3 v1 = Helper.GetPerpendicularVector(normal);
            Vector3 v2 = Vector3.Cross(v1, normal);

            v1      *= 0.5f;
            v2      *= 0.5f;
            vertices = new Vector3[] // Position | Normal
            {
                -v1 - v2, normal,
                -v1 + v2, normal,
                v1 - v2, normal,
                v1 + v2, normal,
            };

            indices = new uint[]
            {
                0, 2, 1,
                2, 3, 1
            };

            vertexArray = GL.GenVertexArray();
            GL.BindVertexArray(vertexArray);

            vertexBuffer = GL.GenBuffer();
            GL.BindBuffer(BufferTarget.ArrayBuffer, vertexBuffer);
            GL.BufferData(BufferTarget.ArrayBuffer, vertices.Length * sizeof(float) * 3, vertices, BufferUsageHint.StaticDraw);

            GL.VertexAttribPointer(0, 3, VertexAttribPointerType.Float, false, 6 * sizeof(float), 0);
            GL.VertexAttribPointer(1, 3, VertexAttribPointerType.Float, false, 6 * sizeof(float), 3 * sizeof(float));
            GL.EnableVertexAttribArray(0);
            GL.EnableVertexAttribArray(1);

            elementBuffer = GL.GenBuffer();
            GL.BindBuffer(BufferTarget.ElementArrayBuffer, elementBuffer);
            GL.BufferData(BufferTarget.ElementArrayBuffer, indices.Length * sizeof(uint), indices, BufferUsageHint.StaticDraw);

            UpdateTransformMatrix();
        }
Exemplo n.º 10
0
        virtual public Transform Step(double time, LocationOptions options)
        {
            Clamp(options);


            var up = new Vector3(normal.x, normal.y, -normal.z);


            Vector3 east = new Vector3(local_orientation.v11, local_orientation.v21, local_orientation.v31);;
            Vector3 north;

            if (options.RotationOptions.HasFlag(RotationOptions.AlignToSurface))
            {
                east  = Vector3.Normalize(east - (Vector3.Dot(east, up) * up));
                north = Vector3.Cross(east, up);
            }
            else
            {
                north = new Vector3(-local_orientation.v12, -local_orientation.v22, -local_orientation.v32);
            }

            var m = new Matrix4x4(east.X, east.Y, east.Z, 0,
                                  up.X, up.Y, up.Z, 0,
                                  north.X, north.Y, north.Z, 0,
                                  0, 0, 0, 1);

            var qm = Quaternion.CreateFromRotationMatrix(m);

            var r = qm * Rotation;

            return(new Transform
            {
                Pos = { X = (float)position.x, Y = (float)position.y, Z = (float)position.z },
                Rot = r
            });
        }
Exemplo n.º 11
0
        /// <summary>
        /// Form new simplex and test in which external Voronoi region the origin lies.
        /// </summary>
        /// <param name="W">Simplex</param>
        /// <param name="w">New point in CSO surface</param>
        /// <returns>New smallest simplex <paramref name="W"/> containing <paramref name="w"/> and closest point to origin.</returns>
        public Simplex BestSimplex(Simplex W, ShapePoint w)
        {
            Simplex result = new Simplex();

            switch (W.count)
            {
            case 0: {
                result.A     = w;
                result.count = 1;
                break;
            }

            case 1: {
                Simplex line = new Simplex();
                line.A     = w;
                line.B     = W.A;
                line.count = 2;
                Vector closest = ClosestToSegment(new Vector(0, 0), w.MinkowskiPoint, W.A.MinkowskiPoint);
                if (closest == w.MinkowskiPoint)
                {
                    result.A     = w;
                    result.count = 1;
                }
                else
                {
                    result.A     = W.A;
                    result.B     = w;
                    result.count = 2;
                }
                break;
            }

            case 2: {
                Vector  d     = new Vector(0, 0) - w.MinkowskiPoint;    // d.negate(); AO = O - A; O = origin (0, 0)
                Vector  e1    = W.A.MinkowskiPoint - w.MinkowskiPoint;  // AB = B - A
                Vector  e2    = W.B.MinkowskiPoint - w.MinkowskiPoint;
                Vector3 e1_3D = new Vector3((float)e1.X, (float)e1.Y, 0);
                Vector3 e2_3D = new Vector3((float)e2.X, (float)e2.Y, 0);
                Vector3 u1    = Vector3.Cross(e1_3D, Vector3.Cross(e1_3D, e2_3D));
                Vector3 v1    = Vector3.Cross(Vector3.Cross(e1_3D, e2_3D), e2_3D);
                if (Vector.Multiply(d, e1) < 0 && Vector.Multiply(d, e2) < 0)
                {
                    result.A     = w;
                    result.count = 1;
                }
                else if (Vector.Multiply(d, e1) > 0 && (d.X * u1.X + d.Y * u1.Y + 0 * u1.Z) > 0)
                {
                    result.A     = W.A;
                    result.B     = w;
                    result.count = 2;
                }
                else if (Vector.Multiply(d, e2) > 0 && (d.X * v1.X + d.Y * v1.Y + 0 * v1.Z) > 0)
                {
                    result.A     = W.B;
                    result.B     = w;
                    result.count = 2;
                }
                else if ((d.X * u1.X + d.Y * u1.Y + 0 * u1.Z < 0) && (d.X * v1.X + d.Y * v1.Y + 0 * v1.Z < 0))
                {
                    result.A     = W.A;
                    result.B     = W.B;
                    result.C     = w;
                    result.count = 3;
                }
                else
                {
                    result = W;
                }
                break;
            }
            }
            return(result);
        }
Exemplo n.º 12
0
        public static MashTrigle[] LoadModel(string filePath, bool negativeZ = false)
        {
            string[] lines = File.ReadAllLines(filePath);

            List <MashTrigle> mashes = new List <MashTrigle>();
            List <Vector3f>   v      = new List <Vector3f>()
            {
                new Vector3f()
            };
            Dictionary <int, List <PW_Trigle> > faceList = new Dictionary <int, List <PW_Trigle> >();
            List <Vector2f> vt = new List <Vector2f>()
            {
                new Vector2f()
            };
            List <Vector3f> vn = new List <Vector3f>()
            {
                new Vector3f()
            };

            MashTrigle       nobj    = null;
            List <PW_Trigle> trigles = new List <PW_Trigle>();

            for (int linecount = 0; linecount < lines.Length; linecount++)
            {
                string line = lines[linecount];
                if (string.IsNullOrWhiteSpace(line) || line.StartsWith('#'))
                {
                    continue;
                }

                float    p0 = 0.0f, p1 = 0.0f, p2 = 0.0f;
                string[] parts = line.Split(LineSplitChars, StringSplitOptions.RemoveEmptyEntries);
                switch (parts[0].ToLower())
                {
                case "v":
                    #region v
                    if (parts.Length != 4)
                    {
                        throw new Exception($"line {linecount} : 缺少参数的行,请求3个,实际为{parts.Length - 1}个");
                    }
                    if (!Float.TryParse(parts[1], out p0))
                    {
                        throw new Exception($"line {linecount} : 不能转换的数据 {parts[1]}");
                    }
                    if (!Float.TryParse(parts[2], out p1))
                    {
                        throw new Exception($"line {linecount} : 不能转换的数据 {parts[2]}");
                    }
                    if (!Float.TryParse(parts[3], out p2))
                    {
                        throw new Exception($"line {linecount} : 不能转换的数据 {parts[3]}");
                    }
                    if (negativeZ)
                    {
                        v.Add(new Vector3f(p0, p1, -p2));
                    }
                    else
                    {
                        v.Add(new Vector3f(p0, p1, p2));
                    }
                    #endregion
                    break;

                case "vt":
                    #region vt
                    if (parts.Length != 3 && parts.Length != 4)
                    {
                        throw new Exception($"line {linecount} : 缺少参数的行,请求2或3个,实际为{parts.Length - 1}个");
                    }
                    if (!Float.TryParse(parts[1], out p0))
                    {
                        throw new Exception($"line {linecount} : 不能转换的数据 {parts[1]}");
                    }
                    if (!Float.TryParse(parts[2], out p1))
                    {
                        throw new Exception($"line {linecount} : 不能转换的数据 {parts[2]}");
                    }
                    vt.Add(new Vector2f(p0, p1));
                    #endregion
                    break;

                case "vn":
                    #region vn
                    if (parts.Length != 4)
                    {
                        throw new Exception($"line {linecount} : 缺少参数的行,请求3个,实际为{parts.Length - 1}个");
                    }
                    if (!Float.TryParse(parts[1], out p0))
                    {
                        throw new Exception($"line {linecount} : 不能转换的数据 {parts[1]}");
                    }
                    if (!Float.TryParse(parts[2], out p1))
                    {
                        throw new Exception($"line {linecount} : 不能转换的数据 {parts[2]}");
                    }
                    if (!Float.TryParse(parts[3], out p2))
                    {
                        throw new Exception($"line {linecount} : 不能转换的数据 {parts[3]}");
                    }
                    if (negativeZ)
                    {
                        vn.Add(Vector3f.Normalize(new Vector3f(p0, p1, -p2)));
                    }
                    else
                    {
                        vn.Add(Vector3f.Normalize(new Vector3f(p0, p1, p2)));
                    }
                    #endregion
                    break;

                case "vp":

                    break;

                case "g":
                    #region g
                    if (trigles != null && trigles.Count > 0)
                    {
                        if (nobj == null)
                        {
                            nobj = new MashTrigle();
                        }
                        nobj.SetTrigles(Smooth(trigles, v, vt, faceList));
                        mashes.Add(nobj);
                    }
                    nobj    = new MashTrigle();
                    trigles = new List <PW_Trigle>();
                    #endregion
                    break;

                case "f":
                    #region f
                    if (parts.Length < 4)
                    {
                        throw new Exception($"line {linecount} : 缺少参数的行,请求至少为3个,实际为{parts.Length - 1}个");
                    }
                    int   pointcount = parts.Length - 1;
                    int[] vidx       = new int[pointcount], vtidx = new int[pointcount], vnidx = new int[pointcount];

                    // 分割顶点信息
                    for (int i = 0; i < pointcount; i++)
                    {
                        string   pinfo = parts[i + 1];
                        string[] infos = pinfo.Split(PInfoSplitChars);
                        vidx[i] = int.Parse(infos[0]);
                        int tmp;
                        if (infos.Length > 1 && int.TryParse(infos[1], out tmp))
                        {
                            vtidx[i] = tmp;
                        }
                        else
                        {
                            vtidx[i] = 0;                                    //-1;
                        }
                        if (infos.Length > 2 && int.TryParse(infos[1], out tmp))
                        {
                            vnidx[i] = tmp;
                        }
                        else
                        {
                            vnidx[i] = 0;                                    //-1;
                        }
                    }

                    // 生成三角形面
                    for (int i = 2; i < pointcount; i++)
                    {
                        PW_Trigle face = new PW_Trigle();
                        face.v0 = vidx[0];
                        face.v1 = vidx[i - 1];
                        face.v2 = vidx[i];

                        {                                 //normal
                            Vector3f e1 = v[face.v1] - v[face.v0], e2 = v[face.v2] - v[face.v0];
                            face.Normal = Vector3f.Normalize(Vector3f.Cross(e1, e2));
                        }
                        {                                 //sp
                                                          //if (vtidx[0] != -1) {
                            face.vt0 = vtidx[0];
                            //}
                            //if (vtidx[i - 1] != -1) {
                            face.vt1 = vtidx[i - 1];
                            //}
                            //if (vtidx[i] != -1) {
                            face.vt2 = vtidx[i];
                            //}
                        }

                        trigles.Add(face);
                        if (!faceList.ContainsKey(face.v0))
                        {
                            faceList[face.v0] = new List <PW_Trigle>();
                        }
                        faceList[face.v0].Add(face);
                        if (!faceList.ContainsKey(face.v1))
                        {
                            faceList[face.v1] = new List <PW_Trigle>();
                        }
                        faceList[face.v1].Add(face);
                        if (!faceList.ContainsKey(face.v2))
                        {
                            faceList[face.v2] = new List <PW_Trigle>();
                        }
                        faceList[face.v2].Add(face);
                    }

                    #endregion
                    break;
                }
            }

            if (trigles != null && trigles.Count > 0)
            {
                if (nobj == null)
                {
                    nobj = new MashTrigle();
                }
                nobj.SetTrigles(Smooth(trigles, v, vt, faceList));
                mashes.Add(nobj);
            }

            return(mashes.ToArray());
        }
Exemplo n.º 13
0
        private void CreateGeometry()
        {
            // Create box
            Geometry box = new Geometry(OptixContext);

            box.PrimitiveCount      = 1;
            box.BoundingBoxProgram  = new OptixProgram(OptixContext, boxPath, "box_bounds");;
            box.IntersectionProgram = new OptixProgram(OptixContext, boxPath, "box_intersect");;
            box["boxmin"].Set(-2.0f, 0.0f, -2.0f);
            box["boxmax"].Set(2.0f, 7.0f, 2.0f);

            Geometry chull = null;

            if (mTutorial >= 9)
            {
                chull = new Geometry(OptixContext);
                chull.PrimitiveCount      = 1u;
                chull.BoundingBoxProgram  = new OptixProgram(OptixContext, shaderPath, "chull_bounds");
                chull.IntersectionProgram = new OptixProgram(OptixContext, shaderPath, "chull_intersect");

                uint    nsides = 6;
                float   radius = 1;
                Vector3 xlate  = new Vector3(-1.4f, 0, -3.7f);

                BufferDesc desc = new BufferDesc()
                {
                    Width = nsides + 2u, Type = BufferType.Input, Format = Format.Float4
                };
                Buffer chullBuffer = new Buffer(OptixContext, desc);

                float        angle  = 0.0f;
                BufferStream stream = chullBuffer.Map();
                for (uint i = 0; i < nsides; i++)
                {
                    angle = (float)i / (float)nsides * (float)Math.PI * 2.0f;
                    float x = (float)Math.Cos(angle);
                    float y = (float)Math.Sin(angle);

                    stream.Write <Vector4>(Utils.CreatePlane(new Vector3(x, 0, y), new Vector3(x * radius, 0, y * radius) + xlate));
                }

                float min = 0.02f;
                float max = 3.5f;
                angle = 5.0f / (float)nsides * (float)Math.PI * 2.0f;
                stream.Write <Vector4>(Utils.CreatePlane(new Vector3(0, -1, 0), new Vector3(0, min, 0) + xlate));
                stream.Write <Vector4>(Utils.CreatePlane(new Vector3((float)Math.Cos(angle), 0.7f, (float)Math.Sin(angle)),
                                                         new Vector3(0, max, 0) + xlate));

                chullBuffer.Unmap();

                chull["planes"].Set(chullBuffer);
                chull["chull_bbmin"].Set(-radius + xlate.X, min + xlate.Y, -radius + xlate.Z);
                chull["chull_bbmax"].Set(radius + xlate.X, max + xlate.Y, radius + xlate.Z);
            }

            // Floor geometry
            Geometry parallelogram = new Geometry(OptixContext);

            parallelogram.PrimitiveCount      = 1;
            parallelogram.BoundingBoxProgram  = new OptixProgram(OptixContext, parrallelPath, "bounds");;
            parallelogram.IntersectionProgram = new OptixProgram(OptixContext, parrallelPath, "intersect");;

            Vector3 anchor = new Vector3(-64.0f, 0.01f, -64.0f);
            Vector3 v1     = new Vector3(128.0f, 0.0f, 0.0f);
            Vector3 v2     = new Vector3(0.0f, 0.0f, 128.0f);
            Vector3 normal = Vector3.Normalize(Vector3.Cross(v2, v1));

            v1 *= 1.0f / (v1.LengthSquared());
            v2 *= 1.0f / (v2.LengthSquared());

            float   d     = Vector3.Dot(normal, anchor);
            Vector4 plane = new Vector4(normal, d);

            parallelogram["plane"].Set(ref plane);
            parallelogram["v1"].Set(ref v1);
            parallelogram["v2"].Set(ref v2);
            parallelogram["anchor"].Set(ref anchor);

            string boxMtrlName   = mTutorial >= 8 ? "box_closest_hit_radiance" : "closest_hit_radiance";
            string floorMtrlName = mTutorial >= 4 ? "floor_closest_hit_radiance" : "closest_hit_radiance";

            Material boxMtrl = new Material(OptixContext);

            boxMtrl.SetSurfaceProgram(0, new SurfaceProgram(OptixContext, RayHitType.Closest, shaderPath, boxMtrlName));
            if (mTutorial >= 3)
            {
                boxMtrl.SetSurfaceProgram(1, new SurfaceProgram(OptixContext, RayHitType.Any, shaderPath, "any_hit_shadow"));
            }

            boxMtrl["Ka"].Set(0.3f, 0.3f, 0.3f);
            boxMtrl["Kd"].Set(0.6f, 0.7f, 0.8f);
            boxMtrl["Ks"].Set(0.8f, 0.9f, 0.8f);
            boxMtrl["phong_exp"].Set(88.0f);
            boxMtrl["reflectivity_n"].Set(0.2f, 0.2f, 0.2f);

            Material floorMtrl = new Material(OptixContext);

            floorMtrl.SetSurfaceProgram(0, new SurfaceProgram(OptixContext, RayHitType.Closest, shaderPath, floorMtrlName));
            if (mTutorial >= 3)
            {
                floorMtrl.SetSurfaceProgram(1, new SurfaceProgram(OptixContext, RayHitType.Any, shaderPath, "any_hit_shadow"));
            }

            floorMtrl["Ka"].Set(0.3f, 0.3f, 0.1f);
            floorMtrl["Kd"].Set(194 / 255.0f * .6f, 186 / 255.0f * .6f, 151 / 255.0f * .6f);
            floorMtrl["Ks"].Set(0.4f, 0.4f, 0.4f);
            floorMtrl["reflectivity"].Set(0.1f, 0.1f, 0.1f);
            floorMtrl["reflectivity_n"].Set(0.05f, 0.05f, 0.05f);
            floorMtrl["phong_exp"].Set(88.0f);
            floorMtrl["tile_v0"].Set(0.25f, 0, .15f);
            floorMtrl["tile_v1"].Set(-.15f, 0, 0.25f);
            floorMtrl["crack_color"].Set(0.1f, 0.1f, 0.1f);
            floorMtrl["crack_width"].Set(0.02f);

            Material glassMtrl = null;

            if (chull != null)
            {
                glassMtrl = new Material(OptixContext);
                glassMtrl.SetSurfaceProgram(0, new SurfaceProgram(OptixContext, RayHitType.Closest, shaderPath, "glass_closest_hit_radiance"));
                glassMtrl.SetSurfaceProgram(1, new SurfaceProgram(OptixContext, RayHitType.Any, shaderPath, mTutorial > 9 ? "glass_any_hit_shadow" : "any_hit_shadow"));

                Vector3 extinction = new Vector3(.80f, .89f, .75f);
                glassMtrl["importance_cutoff"].Set(1e-2f);
                glassMtrl["cutoff_color"].Set(0.34f, 0.55f, 0.85f);
                glassMtrl["fresnel_exponent"].Set(3.0f);
                glassMtrl["fresnel_minimum"].Set(0.1f);
                glassMtrl["fresnel_maximum"].Set(1.0f);
                glassMtrl["refraction_index"].Set(1.4f);
                glassMtrl["refraction_color"].Set(1.0f, 1.0f, 1.0f);
                glassMtrl["reflection_color"].Set(1.0f, 1.0f, 1.0f);
                glassMtrl["refraction_maxdepth"].Set(100);
                glassMtrl["reflection_maxdepth"].Set(100);
                glassMtrl["extinction_constant"].Set((float)Math.Log(extinction.X), (float)Math.Log(extinction.Y), (float)Math.Log(extinction.Z));
                glassMtrl["shadow_attenuation"].Set(0.4f, 0.7f, 0.4f);
            }

            GeometryInstance boxInst = new GeometryInstance(OptixContext);

            boxInst.Geometry = box;
            boxInst.AddMaterial(boxMtrl);

            GeometryInstance parallelInst = new GeometryInstance(OptixContext);

            parallelInst.Geometry = parallelogram;
            parallelInst.AddMaterial(floorMtrl);

            GeometryGroup group = new GeometryGroup(OptixContext);

            group.AddChild(boxInst);
            group.AddChild(parallelInst);
            if (chull != null)
            {
                GeometryInstance chullInst = new GeometryInstance(OptixContext);
                chullInst.Geometry = chull;
                chullInst.AddMaterial(glassMtrl);
                group.AddChild(chullInst);
            }

            group.Acceleration = new Acceleration(OptixContext, AccelBuilder.Bvh, AccelTraverser.Bvh);

            OptixContext["top_object"].Set(group);
            OptixContext["top_shadower"].Set(group);
        }
Exemplo n.º 14
0
        public override void Initialize()
        {
            //Vector3 v1 = Helper.GetPerpendicularVector(normal);
            //Vector3 v2 = Vector3.Cross(v1, normal);
            //v1 *= 0.5f;
            //v2 *= 0.5f;
            //vertices = new Vector3[] // Position | Normal
            //{
            //    -v1 - v2, normal,
            //    -v1 + v2, normal,
            //    v1 - v2, normal,
            //    v1 + v2, normal,
            //};
            //
            //indices = new uint[]
            //{
            //    0, 2, 1,
            //    2, 3, 1
            //};

            List <Vector3> vertexList   = new List <Vector3>();
            List <uint>    triangleList = new List <uint>();

            void AddTriangle(uint a, uint b, uint c)
            {
                triangleList.Add(a);
                triangleList.Add(b);
                triangleList.Add(c);
            }

            Vector3 v1 = Helper.GetPerpendicularVector(normal);
            Vector3 v2 = Vector3.Cross(v1, normal);

            vertexList.Add(new Vector3(0f, 0f, 0f));
            for (int i = 0; i < steps; ++i)
            {
                float angle = ((float)i / steps) * MathF.PI * 2f;
                vertexList.Add(v1 * MathF.Cos(angle) + v2 * MathF.Sin(angle));
            }

            for (uint i = 1; i < steps - 1; ++i)
            {
                AddTriangle(0, i, i + 1);
            }
            AddTriangle(0, steps - 1, 1);

            // Add normals to vertex list
            for (int i = vertexList.Count - 1; i >= 0; --i)
            {
                Vector3 vert = vertexList[i];
                vertexList.Insert(i + 1, normal);
            }

            vertices = vertexList.ToArray();
            indices  = triangleList.ToArray();

            vertexArray = GL.GenVertexArray();
            GL.BindVertexArray(vertexArray);

            vertexBuffer = GL.GenBuffer();
            GL.BindBuffer(BufferTarget.ArrayBuffer, vertexBuffer);
            GL.BufferData(BufferTarget.ArrayBuffer, vertices.Length * sizeof(float) * 3, vertices, BufferUsageHint.StaticDraw);

            GL.VertexAttribPointer(0, 3, VertexAttribPointerType.Float, false, 6 * sizeof(float), 0);
            GL.VertexAttribPointer(1, 3, VertexAttribPointerType.Float, false, 6 * sizeof(float), 3 * sizeof(float));
            GL.EnableVertexAttribArray(0);
            GL.EnableVertexAttribArray(1);

            elementBuffer = GL.GenBuffer();
            GL.BindBuffer(BufferTarget.ElementArrayBuffer, elementBuffer);
            GL.BufferData(BufferTarget.ElementArrayBuffer, indices.Length * sizeof(uint), indices, BufferUsageHint.StaticDraw);

            UpdateTransformMatrix();
        }