Exemplo n.º 1
0
        private Vector3 XXXSteerToEvadeAllDefenders()
        {
            // sum up weighted evasion
            Vector3 evade = Vector3.Zero;

            foreach (CtfEnemy e in Plugin.CtfEnemies)
            {
                Vector3 eOffset   = e.Position - Position;
                float   eDistance = eOffset.Length();

                // xxx maybe this should take into account e's heading? xxx
                float   timeEstimate = 0.5f * eDistance / e.Speed;           //xxx
                Vector3 eFuture      = e.PredictFuturePosition(timeEstimate);

                // annotation
                annotation.CircleXZ(e.Radius, eFuture, Globals.EvadeColor.ToVector3().FromXna(), 20);

                // steering to flee from eFuture (enemy's future position)
                Vector3 flee = SteerForFlee(eFuture);

                float eForwardDistance = Vector3.Dot(Forward, eOffset);
                float behindThreshold  = Radius * -2;

                float distanceWeight = 4 / eDistance;
                float forwardWeight  = ((eForwardDistance > behindThreshold) ? 1.0f : 0.5f);

                Vector3 adjustedFlee = flee * distanceWeight * forwardWeight;

                evade += adjustedFlee;
            }
            return(evade);
        }
Exemplo n.º 2
0
        public override void Redraw(float currentTime, float elapsedTime)
        {
            // selected vehicle (user can mouse click to select another)
            IVehicle selected = Demo.SelectedVehicle;

            // vehicle nearest mouse (to be highlighted)
            IVehicle nearMouse = Demo.VehicleNearestToMouse();

            // update camera
            Demo.UpdateCamera(elapsedTime, selected);

            // draw "ground plane" centered between base and selected vehicle
            Vector3 goalOffset    = Globals.HomeBaseCenter - Demo.Camera.Position;
            Vector3 goalDirection = Vector3.Normalize(goalOffset);
            Vector3 cameraForward = Demo.Camera.xxxls().Forward;
            float   goalDot       = Vector3.Dot(cameraForward, goalDirection);
            float   blend         = Utilities.RemapIntervalClip(goalDot, 1, 0, 0.5f, 0);
            Vector3 gridCenter    = Vector3.Lerp(selected.Position, Globals.HomeBaseCenter, blend);

            Demo.GridUtility(gridCenter);

            // draw the seeker, obstacles and home base
            CtfSeeker.Draw();
            DrawObstacles();
            DrawHomeBase();

            // draw each enemy
            foreach (CtfEnemy enemy in CtfEnemies)
            {
                enemy.Draw();
            }

            // highlight vehicle nearest mouse
            Demo.HighlightVehicleUtility(nearMouse);
        }
Exemplo n.º 3
0
        public Vector3 SteerToEvadeAllDefenders()
        {
            Vector3 evade        = Vector3.Zero;
            float   goalDistance = Vector3.Distance(Globals.HomeBaseCenter, Position);

            // sum up weighted evasion
            foreach (CtfEnemy e in Plugin.CtfEnemies)
            {
                Vector3 eOffset   = e.Position - Position;
                float   eDistance = eOffset.Length();

                float eForwardDistance = Vector3.Dot(Forward, eOffset);
                float behindThreshold  = Radius * 2;
                bool  behind           = eForwardDistance < behindThreshold;
                if ((!behind) || (eDistance < 5))
                {
                    if (eDistance < (goalDistance * 1.2))             //xxx
                    {
                        // const float timeEstimate = 0.5f * eDistance / e.speed;//xxx
                        float   timeEstimate = 0.15f * eDistance / e.Speed;          //xxx
                        Vector3 future       = e.PredictFuturePosition(timeEstimate);

                        annotation.CircleXZ(e.Radius, future, Globals.EvadeColor.ToVector3().FromXna(), 20); // xxx

                        Vector3 offset  = future - Position;
                        Vector3 lateral = Vector3Helpers.PerpendicularComponent(offset, Forward);
                        float   d       = lateral.Length();
                        float   weight  = -1000 / (d * d);
                        evade += (lateral / d) * weight;
                    }
                }
            }
            return(evade);
        }
Exemplo n.º 4
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.º 5
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.º 6
0
        public RangeFit(ColourSet colours, CompressionOptions flags) : base(colours)
        {
            // initialise the metric
            bool perceptual = ((flags & CompressionOptions.ColourMetricPerceptual) != 0);

            m_metric = perceptual ? new Vec3(0.2126f, 0.7152f, 0.0722f) : Vec3.One;

            // initialise the best error
            m_besterror = float.MaxValue;

            // cache some values
            var count   = m_colours.Count;
            var values  = m_colours.Points;
            var weights = m_colours.Weights;

            // get the covariance matrix
            Sym3x3 covariance = Sym3x3.ComputeWeightedCovariance(count, values, weights);

            // compute the principle component
            Vec3 principle = Sym3x3.ComputePrincipleComponent(covariance);

            // get the min and max range as the codebook endpoints
            Vec3 start = Vec3.Zero;
            Vec3 end   = Vec3.Zero;

            if (count > 0)
            {
                float min, max;

                // compute the range
                start = end = values[0];
                min   = max = Vec3.Dot(values[0], principle);
                for (int i = 1; i < count; ++i)
                {
                    float val = Vec3.Dot(values[i], principle);
                    if (val < min)
                    {
                        start = values[i];
                        min   = val;
                    }
                    else if (val > max)
                    {
                        end = values[i];
                        max = val;
                    }
                }
            }

            // clamp the output to [0, 1]
            start = start.Clamp(Vec3.Zero, Vec3.One);
            end   = end.Clamp(Vec3.Zero, Vec3.One);

            // clamp to the grid and save
            m_start = (GRID * start + HALF).Truncate() * GRIDRCP;
            m_end   = (GRID * end + HALF).Truncate() * GRIDRCP;
        }
Exemplo n.º 7
0
        public override RayCastResult Intersection(Ray ray, float nowbest)
        {
            {
                float distance = (Position - ray.Origin).Length();
                if (nowbest + R < distance)
                {
                    return(null);
                }
            }
            Vector3f A = ray.Origin, B = ray.Direction, C = Position;
            Float    a = Vector3f.Dot(B, B);
            Float    b = Vector3f.Dot(B, (A - C)) * 2.0f;
            Float    c = (A - C).LengthSquared() - R * R;

            float drt = b * b - 4 * a * c;

            if (drt < 0)
            {
                return(null);
            }
            drt = Math.Sqrt(drt);
            float x1 = (-b + drt) / a / 2;
            float x2 = (-b - drt) / a / 2;

            if (x1 < 0 && x2 < 0)
            {
                return(null);
            }

            float d;

            if (x1 > 0 && x2 > 0)
            {
                d = Math.Max(x1, x2);
            }
            else if (x1 > 0)
            {
                d = x1;
            }
            else
            {
                d = x2;
            }

            RayCastResult result = new RayCastResult();

            //result.happened = true;
            result.obj      = this;
            result.material = Material;
            result.coords   = ray.Origin + ray.Direction * d;
            result.distance = d;
            result.normal   = Vector3f.Normalize(result.coords - Position);

            return(result);
        }
Exemplo n.º 8
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.º 9
0
        /// <summary>
        /// 返回折射光方向
        /// </summary>
        /// <param name="dir"></param>
        /// <param name="niOverNt">入射折射率/出射折射率</param>
        /// <returns></returns>
        public static Vector3f Refract(Vector3f dir, Vector3f normal, float niOverNt)
        {
            dir = -dir;
            Float cosAlpha   = Vector3f.Dot(dir, normal);
            Float sinAlphaSq = 1.0f - cosAlpha * cosAlpha;
            Float sinBetaSq  = niOverNt * niOverNt * sinAlphaSq;

            Float    cosBetaSq = 1.0f - sinBetaSq;
            Float    cosBeta   = Math.Sqrt(cosBetaSq);
            Vector3f re        = ((normal * cosAlpha) - dir) * niOverNt - normal * cosBeta;

            return(re);
        }
Exemplo n.º 10
0
        public static float Angle(this Vector3d A, Vector3d B)
        {
            float vDot = Vector3d.Dot(A, B) / (A.Length() * B.Length());

            if (vDot < -1.0f)
            {
                vDot = -1.0f;
            }
            if (vDot > 1.0f)
            {
                vDot = 1.0f;
            }

            return((float)Math.Acos(vDot));
        }
Exemplo n.º 11
0
        // called when steerToAvoidCloseNeighbors decides steering is required
        public void AnnotateAvoidCloseNeighbor(IVehicle other)
        {
            // draw the word "Ouch!" above colliding vehicles
            bool    headOn   = Vector3.Dot(Forward, other.Forward) < 0;
            Color   green    = new Color((byte)(255.0f * 0.4f), (byte)(255.0f * 0.8f), (byte)(255.0f * 0.1f));
            Color   red      = new Color((byte)(255.0f * 1), (byte)(255.0f * 0.1f), 0);
            Color   color    = headOn ? red : green;
            String  text     = headOn ? "OUCH!" : "pardon me";
            Vector3 location = Position + new Vector3(0, 0.5f, 0);

            if (annotation.IsEnabled)
            {
                Drawing.Draw2dTextAt3dLocation(text, location, color);
            }
        }
Exemplo n.º 12
0
        //--------------------------------OTHERS----------------------------------------//

        /**
         * Computes the distance from the line point to another point
         *
         * @param otherPoint the point to compute the distance from the line point. The point
         * is supposed to be on the same line.
         * @return points distance. If the point submitted is behind the direction, the
         * distance is negative
         */
        public double computePointToPointDistance(Point3d otherPoint)
        {
            //float distance = otherPoint.distance(point);
            float distance = Vector3d.Distance(otherPoint, point);

            Vector3d vec = Vector3d.Normalize(new Vector3d(otherPoint.X - point.X, otherPoint.Y - point.Y, otherPoint.Z - point.Z));

            if (Vector3d.Dot(vec, direction) < 0)
            {
                return(-distance);
            }
            else
            {
                return(distance);
            }
        }
Exemplo n.º 13
0
        /// <summary>
        /// 返回折射光方向和能量强度
        /// </summary>
        /// <param name="dir"></param>
        /// <param name="niOverNt"></param>
        /// <returns></returns>
        public static (float, Vector3) Refract(Vector3 dir, Vector3 normal, float niOverNt)
        {
            dir = -Vector3.Normalize(dir);
            float cosAlpha     = Vector3.Dot(dir, normal);
            float discriminant = 1.0f - niOverNt * niOverNt * (1.0f - cosAlpha * cosAlpha);

            if (discriminant > 0)
            {
                float   cosGamma = MathF.Sqrt(discriminant);
                Vector3 re       = ((normal * cosAlpha) - dir) * niOverNt - normal * cosGamma;
                return(1.0f - Schlick(cosAlpha, niOverNt), re);
            }
            else
            {
                return(float.NegativeInfinity, Vector3.Zero);
            }
        }
Exemplo n.º 14
0
        private bool ConstructOrdering(Vec3 axis)
        {
            // cache some values
            var count  = m_colours.Count;
            var values = m_colours.Points;

            // build the list of dot products
            var dps = new float[count];

            for (int i = 0; i < count; ++i)
            {
                dps[i]     = Vec3.Dot(values[i], axis);
                m_order[i] = (Byte)i;
            }

            // stable sort using them
            for (int i = 0; i < dps.Length; ++i)
            {
                for (int j = i; j > 0 && dps[j] < dps[j - 1]; --j)
                {
                    dps.SwapElements(j, j - 1);
                    m_order.SwapElements(j, j - 1);
                }
            }

            // copy the ordering and weight all the points
            var unweighted = m_colours.Points;
            var weights    = m_colours.Weights;

            for (int i = 0; i < count; ++i)
            {
                int j = m_order[i];

                m_weights[i]    = weights[j];
                m_unweighted[i] = new Vec4(unweighted[j], 1);

                m_weighted[i] = m_unweighted[i] * m_weights[i];
            }

            return(true);
        }
Exemplo n.º 15
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.º 16
0
        private bool ConstructOrdering(Vec3 axis, int iteration)
        {
            // cache some values
            var count  = m_colours.Count;
            var values = m_colours.Points;

            var orderIndex = 16 * iteration;

            // build the list of dot products
            var dps = new float[count];

            for (int i = 0; i < count; ++i)
            {
                dps[i] = Vec3.Dot(values[i], axis);
                m_order[orderIndex + i] = (Byte)i;
            }

            // stable sort using them
            for (int i = 0; i < dps.Length; ++i)
            {
                for (int j = i; j > 0 && dps[j] < dps[j - 1]; --j)
                {
                    dps.SwapElements(j, j - 1);
                    m_order.SwapElements(orderIndex + j, orderIndex + j - 1);
                }
            }

            // check this ordering is unique
            for (int it = 0; it < iteration; ++it)
            {
                var  prevIdx = 16 * it;
                bool same    = true;
                for (int i = 0; i < count; ++i)
                {
                    if (m_order[orderIndex + i] != m_order[prevIdx + i])
                    {
                        same = false;
                        break;
                    }
                }
                if (same)
                {
                    return(false);
                }
            }

            // copy the ordering and weight all the points
            var unweighted = m_colours.Points;
            var weights    = m_colours.Weights;

            m_xsum_wsum = Vec4.Zero;

            for (int i = 0; i < count; ++i)
            {
                int j = m_order[orderIndex + i];
                var p = new Vec4(unweighted[j], 1);
                var w = new Vec4(weights[j]);
                var x = p * w;
                m_points_weights[i] = x;
                m_xsum_wsum        += x;
            }

            return(true);
        }
Exemplo n.º 17
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.º 18
0
        /**
         * Classifies the face based on the ray trace technique
         *
         * @param object object3d used to compute the face status
         */
        public void rayTraceClassify(Object3D obj)
        {
            //creating a ray starting starting at the face baricenter going to the normal direction
            Point3d p0 = new Point3d();

            p0.X = (v1.X + v2.X + v3.X) / 3.0f;
            p0.Y = (v1.Y + v2.Y + v3.Y) / 3.0f;
            p0.Z = (v1.Z + v2.Z + v3.Z) / 3.0f;
            Line ray = new Line(getNormal(), p0);

            bool    success;
            double  dotProduct, distance;
            Point3d?intersectionPoint;
            Face    closestFace = null;
            double  closestDistance;

            do
            {
                success         = true;
                closestDistance = Double.MaxValue;
                //for each face from the other solid...
                for (int i = 0; i < obj.getNumFaces(); i++)
                {
                    Face face = obj.getFace(i);
                    //dotProduct = face.getNormal().dot(ray.getDirection());

                    dotProduct = Vector3d.Dot(face.getNormal(), ray.getDirection());

                    intersectionPoint = ray.computePlaneIntersection(face.getNormal(), face.v1.getPosition());


                    //if ray intersects the plane...
                    if (intersectionPoint != null)
                    {
                        distance = ray.computePointToPointDistance(intersectionPoint.Value);

                        //if ray lies in plane...
                        if (Math.Abs(distance) < TOL && Math.Abs(dotProduct) < TOL)
                        {
                            //disturb the ray in order to not lie into another plane
                            ray.perturbDirection();
                            success = false;
                            break;
                        }

                        //if ray starts in plane...
                        if (Math.Abs(distance) < TOL && Math.Abs(dotProduct) > TOL)
                        {
                            //if ray intersects the face...
                            if (face.hasPoint(intersectionPoint.Value))
                            {
                                //faces coincide
                                closestFace     = face;
                                closestDistance = 0;
                                break;
                            }
                        }

                        //if ray intersects plane...
                        else if (Math.Abs(dotProduct) > TOL && distance > TOL)
                        {
                            if (distance < closestDistance)
                            {
                                //if ray intersects the face;
                                if (face.hasPoint(intersectionPoint.Value))
                                {
                                    //this face is the closest face untill now
                                    closestDistance = distance;
                                    closestFace     = face;
                                }
                            }
                        }
                    }
                }
            } while (success == false);

            //none face found: outside face
            if (closestFace == null)
            {
                status = OUTSIDE;
            }
            //face found: test dot product
            else
            {
                //dotProduct = closestFace.getNormal().dot(ray.getDirection());
                dotProduct = Vector3d.Dot(closestFace.getNormal(), ray.getDirection());

                //distance = 0: coplanar faces
                if (Math.Abs(closestDistance) < TOL)
                {
                    if (dotProduct > TOL)
                    {
                        status = SAME;
                    }
                    else if (dotProduct < -TOL)
                    {
                        status = OPPOSITE;
                    }
                }

                //dot product > 0 (same direction): inside face
                else if (dotProduct > TOL)
                {
                    status = INSIDE;
                }

                //dot product < 0 (opposite direction): outside face
                else if (dotProduct < -TOL)
                {
                    status = OUTSIDE;
                }
            }
        }
Exemplo n.º 19
0
        /// <summary>
        /// 相交点辐射光
        /// </summary>
        /// <param name="point"></param>
        /// <param name="normal"></param>
        /// <param name="deep"></param>
        /// <returns></returns>
        public virtual Light IntersectLight(Vector3 point, Vector3 dir, Vector3 normal, int deep)
        {
#if RayDebugger
            SceneDebug Debugger = Scene.debugger;
            if (Debugger != null)
            {
                Debugger.BeginBranch(point);
            }
#endif

            Light returnlight = default;
            // 发光体返回发光颜色
            if (Material.LightAble)
            {
                returnlight = Material.LightColor;
                goto returnPoint;
            }
            // 递归深度极限
            if (deep <= 1)
            {
                returnlight = Material.BaseColor * 0.3f;
                goto returnPoint;
            }

            dir = Vector3.Normalize(dir);
            bool IsBackFace = false;
            if (Vector3.Dot(dir, normal) > 0)               // 背面
            {
                IsBackFace = true;
                normal     = -normal;
            }

            #region 计算追踪光线总数
            int traceRayNum = RenderConfiguration.Configurations.ReflectSmapingLevel - RenderConfiguration.Configurations.RayTraceDeep + deep;
            {
                traceRayNum = (int)(traceRayNum * Material.AMetalDegree);
                if (traceRayNum < 1)
                {
                    traceRayNum = 1;
                }
                traceRayNum = traceRayNum * 3 - 2;
            }
            #endregion

            #region 计算折射光
            Light refractl     = default;         // 折射光
            float refractPower = 0.0f;            // 折射光强度
            if (Material.IsTransparent)
            {
                float riindex = Material.RefractiveIndices;
                if (!IsBackFace)
                {
                    riindex = 1.0f / riindex;
                }
                // 计算折射光线
                (float pow, Vector3 rdir) = Tools.Refract(dir, normal, riindex);
                if (pow < 0)
                {
                    goto endRefract;
                }

                refractPower = pow * Material.TransparentIndex;

                int raycount = (int)(traceRayNum * refractPower);
                traceRayNum -= raycount;

                float randomScale = Material.AMetalDegree * Material.AMetalDegree * 0.5f;
                //raycount = (int)(traceRayNum * randomScale);
                //raycount = (int)(traceRayNum * Material.AMetalDegree);
                if (raycount < 1 && refractPower > 0.00001)
                {
                    raycount = 1;
                }

                if (raycount == 0)
                {
                    refractl = Material.BaseColor;
                    goto endRefract;
                }

                rdir = normal * randomScale + rdir * (1.0f - randomScale);

                for (int nsmap = 0; nsmap < raycount; nsmap++)
                {
                    Vector3 raydir = Tools.RandomPointInSphere() * randomScale + rdir;

                    Ray r = new Ray(point, raydir);
                    //Console.WriteLine('\t' + this.Name + " [refract] : " + r);
                    (Light c, float distance) = Scene.Light(r, deep - 1, this);

                    if (IsBackFace)                       //内部光线,进行吸收计算
                    {
                        float xsl = Math.Log(distance + 1.0f) + 1.0f;
                        refractl *= Material.BaseColor / xsl;
                    }
                    refractl += c;
                }
                refractl /= raycount;
            }

endRefract:
            #endregion

            #region 计算反射光
            Light reflectl = default;             // 反射光
            {
                int raycount = traceRayNum;
                if (raycount < 1)
                {
                    if (refractPower < 0.99f)
                    {
                        raycount = 1;
                    }
                    else
                    {
                        reflectl = Material.BaseColor;
                        goto endReflact;
                    }
                }

                Vector3 spO;
                {
                    //Vector3 spRO = Tools.Reflect(dir, normal);
                    Vector3 spRO = Vector3.Reflect(dir, normal);
                    //spO = normal * (1.0f - Material.MetalDegree) + spRO * Material.MetalDegree;
                    spO = Vector3.Lerp(normal, spRO, Material.MetalDegree);
                }
                for (int nsmap = 0; nsmap < raycount; nsmap++)
                {
                    Vector3 tp     = Tools.RandomPointInSphere() * Material.AMetalDegree + spO;
                    Vector3 raydir = tp;
                    while (raydir.LengthSquared() < 0.1)
                    {
                        tp     = Tools.RandomPointInSphere() + spO;
                        raydir = tp;
                    }

                    Ray r = new Ray(point, raydir);
                    //Console.WriteLine('\t' + this.Name + " [reflact] : " + r);
                    (Light c, float _) = Scene.Light(r, deep - 1, this);                     //, this);
                    reflectl          += c;
                }
                reflectl /= raycount;
                reflectl *= (0.06f * Material.MetalDegree + 0.93f) * Material.BaseColor;
            }
            #endregion

            returnlight = refractl * refractPower + reflectl * (1.0f - refractPower);
endReflact:
returnPoint:
#if RayDebugger
            if (Debugger != null)
            {
                Debugger.EndBranch();
            }
#endif
            return(returnlight);
        }
Exemplo n.º 20
0
 public static byte GetLuminance(this Vector3 rgb)
 => (((int)(Math.Round(Vector3.Dot(rgb, new Vector3(66, 129, 25))) + 128) >> 8) + 16).ToByte();
Exemplo n.º 21
0
 /// <summary>
 /// 获取入射方向在法线n的反射
 /// </summary>
 /// <param name="dir"></param>
 /// <param name="n"></param>
 /// <returns></returns>
 public static Vector3 Reflect(Vector3 dir, Vector3 n)
 {
     return(dir - Vector3.Dot(dir, n) * 2.0f * n);
 }
Exemplo n.º 22
0
        // is there a clear path to the goal?
        private bool IsPathToGoalClear()
        {
            float sideThreshold   = Radius * 8.0f;
            float behindThreshold = Radius * 2.0f;

            Vector3 goalOffset    = Globals.HomeBaseCenter - Position;
            float   goalDistance  = goalOffset.Length();
            Vector3 goalDirection = goalOffset / goalDistance;

            bool goalIsAside = this.IsAside(Globals.HomeBaseCenter, 0.5f);

            // for annotation: loop over all and save result, instead of early return
            bool xxxReturn = true;

            // loop over enemies
            foreach (CtfEnemy e in Plugin.CtfEnemies)
            {
                float   eDistance        = Vector3.Distance(Position, e.Position);
                float   timeEstimate     = 0.3f * eDistance / e.Speed;       //xxx
                Vector3 eFuture          = e.PredictFuturePosition(timeEstimate);
                Vector3 eOffset          = eFuture - Position;
                float   alongCorridor    = Vector3.Dot(goalDirection, eOffset);
                bool    inCorridor       = ((alongCorridor > -behindThreshold) && (alongCorridor < goalDistance));
                float   eForwardDistance = Vector3.Dot(Forward, eOffset);

                // xxx temp move this up before the conditionals
                annotation.CircleXZ(e.Radius, eFuture, Globals.ClearPathColor.ToVector3().FromXna(), 20);             //xxx

                // consider as potential blocker if within the corridor
                if (inCorridor)
                {
                    Vector3 perp           = eOffset - (goalDirection * alongCorridor);
                    float   acrossCorridor = perp.Length();
                    if (acrossCorridor < sideThreshold)
                    {
                        // not a blocker if behind us and we are perp to corridor
                        float eFront = eForwardDistance + e.Radius;

                        //annotation.annotationLine (position, forward*eFront, gGreen); // xxx
                        //annotation.annotationLine (e.position, forward*eFront, gGreen); // xxx

                        // xxx
                        // std::ostringstream message;
                        // message << "eFront = " << std::setprecision(2)
                        //         << std::setiosflags(std::ios::fixed) << eFront << std::ends;
                        // draw2dTextAt3dLocation (*message.str(), eFuture, gWhite);

                        bool eIsBehind             = eFront < -behindThreshold;
                        bool eIsWayBehind          = eFront < (-2 * behindThreshold);
                        bool safeToTurnTowardsGoal = ((eIsBehind && goalIsAside) || eIsWayBehind);

                        if (!safeToTurnTowardsGoal)
                        {
                            // this enemy blocks the path to the goal, so return false
                            annotation.Line(Position, e.Position, Globals.ClearPathColor.ToVector3().FromXna());
                            // return false;
                            xxxReturn = false;
                        }
                    }
                }
            }

            // no enemies found along path, return true to indicate path is clear
            // clearPathAnnotation (sideThreshold, behindThreshold, goalDirection);
            // return true;
            //if (xxxReturn)
            ClearPathAnnotation(sideThreshold, behindThreshold, goalDirection);
            return(xxxReturn);
        }
Exemplo n.º 23
0
 public static byte GetIntensity(this Vector3 rgb)
 => Vector3.Dot(rgb, new Vector3(1 / 3f)).ToByte();