コード例 #1
0
        public override LightSample Sample(Geometry geometry, Vector3 position)
        {
            Vector3 delta = this.position - position;
            double  rr    = delta.SqrLength();
            double  r     = Math.Sqrt(rr);
            Vector3 l     = delta / r;
            double  spot;
            double  SdotL = vector ^ l;

            if (SdotL >= cosTheta)
            {
                spot = 1;
            }
            else if (SdotL <= cosPhi)
            {
                spot = 0;
            }
            else
            {
                spot = Math.Pow((SdotL - cosPhi) * baseMultiplier, falloff);
            }
            if (shadow)
            {
                var shadowRay    = new Ray3(position, l);
                var shadowResult = geometry.Intersect(shadowRay);
                if (shadowResult.Geometry != null && shadowResult.Distance <= r)
                {
                    return(LightSample.Zero);
                }
            }
            double attenuation = 1 / rr;

            return(new LightSample(l, intensity * (attenuation * spot)));
        }
コード例 #2
0
        public MovingBlocksRaycastResult?Raycast(Vector3 start, Vector3 end, bool extendToFillCells)
        {
            Ray3        ray         = new Ray3(start, Vector3.Normalize(end - start));
            BoundingBox boundingBox = new BoundingBox(Vector3.Min(start, end), Vector3.Max(start, end));

            m_result.Clear();
            FindMovingBlocks(boundingBox, extendToFillCells, m_result);
            float          num            = float.MaxValue;
            MovingBlockSet movingBlockSet = null;

            foreach (MovingBlockSet item in m_result)
            {
                BoundingBox box  = item.BoundingBox(extendToFillCells);
                float?      num2 = ray.Intersection(box);
                if (num2.HasValue && num2.Value < num)
                {
                    num            = num2.Value;
                    movingBlockSet = item;
                }
            }
            if (movingBlockSet != null)
            {
                MovingBlocksRaycastResult value = default(MovingBlocksRaycastResult);
                value.Ray            = ray;
                value.Distance       = num;
                value.MovingBlockSet = movingBlockSet;
                return(value);
            }
            return(null);
        }
コード例 #3
0
ファイル: Test_IntrRay3Plane3.cs プロジェクト: Maestroxr/Math
        private void OnDrawGizmos()
        {
            Ray3   ray   = CreateRay3(Ray);
            Plane3 plane = CreatePlane3(Plane);

            IntersectionTypes intersectionType;
            bool           test = Intersection.TestRay3Plane3(ref ray, ref plane, out intersectionType);
            Ray3Plane3Intr info;
            bool           find = Intersection.FindRay3Plane3(ref ray, ref plane, out info);

            FiguresColor();
            DrawPlane(ref plane, Plane);
            DrawRay(ref ray);

            if (find)
            {
                ResultsColor();
                DrawPoint(info.Point);
            }

            LogInfo(info.IntersectionType + " " + info.RayParameter);
            if (test != find)
            {
                LogError("test != find");
            }
            if (intersectionType != info.IntersectionType)
            {
                LogError("intersectionType != info.IntersectionType");
            }
        }
コード例 #4
0
        internal static Vector3 Color(Ray3 r, HitableList world, int depth)
        {
            HitRecord record = world.Hit(r, 0.01, 10000);

            if (null != record)
            {
                if (depth < 50)
                {
                    ScatterRecord sr = record.Material.Scatter(r, record);
                    if (null != sr)
                    {
                        return(sr.Attenuation * Color(sr.Scatter, world, depth + 1));
                    }
                }

                // Either got absorbed by material or this ray refracted/reflected 50 times.
                // Don't want to go more than 50 depth so stop here in that case.
                return(BlackColor);
            }

            Vector3 unitDir = r.Direction.ToUnitVector();
            double  t       = 0.5 * (unitDir.Y + 1.0);

            return((1.0 - t) * WhiteColor + t * SkyColor);
        }
コード例 #5
0
ファイル: Bounds3.cs プロジェクト: polytronicgr/Axiverse
        public bool Intersects(Ray3 ray)
        {
            float near = 0;
            float far  = float.PositiveInfinity;

            return(IntersectsLine(ref ray.Origin, ref ray.Direction, ref near, ref far));
        }
コード例 #6
0
ファイル: TrSphere.cs プロジェクト: ventor3000/biolum
        public override bool HitTest(Ray3 ray, out double t)
        {
            ray = ray.Transform(InvPosition);

            double dx = ray.Direction.X;
            double dy = ray.Direction.Y;
            double dz = ray.Direction.Z;
            double x0 = ray.Position.X;
            double y0 = ray.Position.Y;
            double z0 = ray.Position.Z;

            double a = 1.0; //assume ray direction is normalized   dx * dx + dy * dy + dz * dz;
            double b = 2.0 * (x0 * dx + y0 * dy + z0 * dz);
            double c = x0 * x0 + y0 * y0 + z0 * z0 - rad * rad;

            bool found = false;

            t = double.MaxValue;
            foreach (var tt in RealPolynomial.SolveQuadric(a, b, c))
            {
                if (tt > 1e-4 && tt < t)
                {
                    t     = tt;
                    found = true;
                }
            }

            return(found);
        }
コード例 #7
0
        public void NotEquals_TrueForNotEqual()
        {
            var a = new Ray3(new Vector3(1, 2, 3), Vector3.UnitY);
            var b = new Ray3(new Vector3(1, 2, 3), Vector3.UnitZ);

            Assert.IsTrue(a != b);
        }
コード例 #8
0
        public void NotEquals_FalseForEqual()
        {
            var a = new Ray3(new Vector3(1, 2, 3), Vector3.UnitY);
            var b = a;

            Assert.IsFalse(a != b);
        }
コード例 #9
0
    void Update()
    {
        Vec3 point;

        // hit X plane
        var ray = new Ray3(new Vector3(-.5f, -.5f, -.5f), new Vector3(.75f, .2f, .5f).normalized);

        Debug.DrawLine(ray.origin.ToVector3(), (ray.origin + (ray.direction * 5)).ToVector3(), Color.green, 0, false);
        if (ray.IntersectPlaneX(.5f, out point))
        {
            Debug.DrawLine(ray.origin.ToVector3(), point.ToVector3(), Color.red, 0, false);
        }

        // hit Y plane
        ray = new Ray3(new Vector3(-.5f, -.5f, -.5f), new Vector3(.3f, .75f, .5f).normalized);
        Debug.DrawLine(ray.origin.ToVector3(), (ray.origin + (ray.direction * 5)).ToVector3(), Color.green, 0, false);
        if (ray.IntersectPlaneY(.5f, out point))
        {
            Debug.DrawLine(ray.origin.ToVector3(), point.ToVector3(), Color.red, 0, false);
        }

        // hit Z plane
        ray = new Ray3(new Vector3(-.5f, -.5f, -.5f), new Vector3(.3f, .2f, 1).normalized);
        Debug.DrawLine(ray.origin.ToVector3(), (ray.origin + (ray.direction * 5)).ToVector3(), Color.green, 0, false);
        if (ray.IntersectPlaneZ(.5f, out point))
        {
            Debug.DrawLine(ray.origin.ToVector3(), point.ToVector3(), Color.red, 0, false);
        }
    }
コード例 #10
0
        public bool Use(Ray3 ray)
        {
            if (Use1 != null)
            {
                return(Use1(ray));
            }
            int   num   = Terrain.ExtractContents(ActiveBlockValue);
            Block block = BlocksManager.Blocks[num];

            if (!CanUseTool(ActiveBlockValue))
            {
                ComponentPlayer?.ComponentGui.DisplaySmallMessage(string.Format(LanguageControl.Get(fName, 1), block.PlayerLevelRequired, block.GetDisplayName(m_subsystemTerrain, ActiveBlockValue)), Color.White, blinking: true, playNotificationSound: true);
                Poke(forceRestart: false);
                return(false);
            }
            SubsystemBlockBehavior[] blockBehaviors = m_subsystemBlockBehaviors.GetBlockBehaviors(num);
            for (int i = 0; i < blockBehaviors.Length; i++)
            {
                if (blockBehaviors[i].OnUse(ray, this))
                {
                    Poke(forceRestart: false);
                    return(true);
                }
            }
            return(false);
        }
コード例 #11
0
        private void OnDrawGizmos()
        {
            Ray3      ray      = CreateRay3(Ray);
            Triangle3 triangle = CreateTriangle3(V0, V1, V2);

            IntersectionTypes intersectionType;
            bool test = Intersection.TestRay3Triangle3(ref ray, ref triangle, out intersectionType);
            Ray3Triangle3Intr info;
            bool find = Intersection.FindRay3Triangle3(ref ray, ref triangle, out info);

            FiguresColor();
            DrawRay(ref ray);
            DrawTriangle(ref triangle);

            if (find)
            {
                ResultsColor();
                DrawPoint(info.Point);
            }

            LogInfo(info.IntersectionType);
            if (test != find)
            {
                LogError("test != find");
            }
            if (intersectionType != info.IntersectionType)
            {
                LogError("intersectionType != info.IntersectionType");
            }
        }
コード例 #12
0
        private void OnDrawGizmos()
        {
            Ray3     ray          = CreateRay3(Ray);
            Plane3   polygonPlane = CreatePlane3(PolygonPlane);
            Polygon3 polygon      = new Polygon3(PolygonPoints.Length, polygonPlane);

            for (int i = 0; i < PolygonPoints.Length; ++i)
            {
                polygon.SetVertexProjected(i, PolygonPoints[i].position);
            }
            polygon.UpdateEdges();

            Ray3Polygon3Intr info;
            bool             find = Intersection.FindRay3Polygon3(ref ray, polygon, out info);

            FiguresColor();
            DrawPolygon(polygon);
            DrawRay(ref ray);

            if (find)
            {
                ResultsColor();
                DrawPoint(info.Point);
            }

            LogInfo(info.IntersectionType);
        }
コード例 #13
0
ファイル: Octree.cs プロジェクト: lijiancheng0614/RayTracer
        public IntersectResult Intersect(Ray3 ray, double maxDistance)
        {
            if (!BoundingBox.Intersect(ray, maxDistance))
            {
                return(IntersectResult.NoHit());
            }
            double          minDistance = maxDistance;
            IntersectResult minResult   = IntersectResult.NoHit();

            if (nodeTriangles != null)
            {
                foreach (var triangle in nodeTriangles)
                {
                    IntersectResult result = triangle.Intersect(ray, minDistance);
                    if (result.Geometry != null && result.Distance < minDistance)
                    {
                        minDistance = result.Distance;
                        minResult   = result;
                    }
                }
            }
            if (children != null)
            {
                foreach (var child in children)
                {
                    IntersectResult result = child.Intersect(ray, minDistance);
                    if (result.Geometry != null && result.Distance < minDistance)
                    {
                        minDistance = result.Distance;
                        minResult   = result;
                    }
                }
            }
            return(minResult);
        }
コード例 #14
0
        /// <summary>
        /// gets position on surface of specified entity
        /// </summary>
        /// <param name="position">the position to start looking at</param>
        /// <param name="entity">the entity to query</param>
        /// <returns></returns>
        public static bool GetPositionOnSurface(ref Vector3 position, Entity entity, out Vector3 surfacePosition)
        {
            Debug.Assert(entity.HasProperty("collision"));
            Ray3 ray = new Ray3(position + 1000 * Vector3.UnitY, -Vector3.UnitY);

            return(Game.Instance.Simulation.CollisionManager.GetIntersectionPoint(ref ray, entity, out surfacePosition));
        }
コード例 #15
0
        private void OnDrawGizmos()
        {
            Ray3 ray = CreateRay3(Ray);
            AAB3 box = CreateAAB3(Box_Point0, Box_Point1);

            bool         test = Intersection.TestRay3AAB3(ref ray, ref box);
            Ray3AAB3Intr info;
            bool         find = Intersection.FindRay3AAB3(ref ray, ref box, out info);

            FiguresColor();
            DrawRay(ref ray);
            DrawAAB(ref box);

            if (find)
            {
                ResultsColor();
                if (info.IntersectionType == IntersectionTypes.Point)
                {
                    DrawPoint(info.Point0);
                }
                else if (info.IntersectionType == IntersectionTypes.Segment)
                {
                    DrawSegment(info.Point0, info.Point1);
                    DrawPoint(info.Point0);
                    DrawPoint(info.Point1);
                }
            }

            LogInfo(info.IntersectionType);
            if (test != find)
            {
                LogError("test != find");
            }
        }
コード例 #16
0
        public void RaycastParticle(Particle particle)
        {
            particle.YLimit         = m_yLimit;
            particle.GenerateSplash = true;
            Block block = BlocksManager.Blocks[Terrain.ExtractContents(m_topmostValue)];

            if (!block.IsTransparent)
            {
                return;
            }
            Ray3        ray = new Ray3(new Vector3(particle.Position.X - (float)Point.X, 1f, particle.Position.Z - (float)Point.Y), -Vector3.UnitY);
            int         nearestBoxIndex;
            BoundingBox nearestBox;
            float?      num = block.Raycast(ray, m_subsystemWeather.SubsystemTerrain, m_topmostValue, useInteractionBoxes: false, out nearestBoxIndex, out nearestBox);

            if (num.HasValue)
            {
                particle.YLimit -= num.Value;
                return;
            }
            particle.YLimit -= 1f;
            if (BlocksManager.Blocks[Terrain.ExtractContents(m_topmostBelowValue)].IsFaceTransparent(m_subsystemWeather.SubsystemTerrain, 4, m_topmostBelowValue))
            {
                particle.GenerateSplash = false;
            }
        }
コード例 #17
0
        public void Trace(Camera cam, Painter p)
        {
            /*  for (int y = 300; y < cam.Height; y++)
             * {
             *    for (int x = 462; x < cam.Width; x++)
             *    {
             */
            for (int y = 0; y < cam.Height; y++)
            {
                for (int x = 0; x < cam.Width; x++)
                {
                    Ray3 ray = cam.GetRay(x, y);
                    RGB  col = GetColor(ray, 0);

                    p.SetPixel(462, 300, Colors.Wheat);

                    if (col != null)
                    {
                        p.SetPixel(x, y, col.ToInt());
                    }
                    else
                    {
                        p.SetPixel(x, y, Colors.Black);
                    }
                }
            }
        }
コード例 #18
0
 public override bool OnUse(Ray3 ray, ComponentMiner componentMiner)
 {
     _ = componentMiner.Inventory;
     if (Terrain.ExtractContents(componentMiner.ActiveBlockValue) == 178)
     {
         TerrainRaycastResult?terrainRaycastResult = componentMiner.Raycast <TerrainRaycastResult>(ray, RaycastMode.Digging);
         if (terrainRaycastResult.HasValue)
         {
             Vector3 position = terrainRaycastResult.Value.HitPoint();
             DynamicArray <ComponentBody> dynamicArray = new DynamicArray <ComponentBody>();
             m_subsystemBodies.FindBodiesInArea(new Vector2(position.X, position.Z) - new Vector2(8f), new Vector2(position.X, position.Z) + new Vector2(8f), dynamicArray);
             if (dynamicArray.Count((ComponentBody b) => b.Entity.ValuesDictionary.DatabaseObject.Name == "Boat") < 6)
             {
                 Entity entity = DatabaseManager.CreateEntity(base.Project, "Boat", throwIfNotFound: true);
                 entity.FindComponent <ComponentFrame>(throwOnError: true).Position      = position;
                 entity.FindComponent <ComponentFrame>(throwOnError: true).Rotation      = Quaternion.CreateFromAxisAngle(Vector3.UnitY, m_random.Float(0f, (float)Math.PI * 2f));
                 entity.FindComponent <ComponentSpawn>(throwOnError: true).SpawnDuration = 0f;
                 base.Project.AddEntity(entity);
                 componentMiner.RemoveActiveTool(1);
                 m_subsystemAudio.PlaySound("Audio/BlockPlaced", 1f, 0f, position, 3f, autoDelay: true);
             }
             else
             {
                 componentMiner.ComponentPlayer?.ComponentGui.DisplaySmallMessage(LanguageControl.Get(fName, 1), Color.White, blinking: true, playNotificationSound: false);
             }
             return(true);
         }
     }
     return(false);
 }
コード例 #19
0
        private bool findDragTarget(Ray3 cameraRay)
        {
            var matches = PoseableObjectsManager.findPoseable(cameraRay);

            foreach (var match in matches.Results)
            {
                var bone = match.PoseableIdentifier.PoseHandler.Bone;
                if (bone != null)
                {
                    if (bone.Pinned)
                    {
                        repinBone   = true;
                        bone.Pinned = false;
                    }
                    else
                    {
                        repinBone = false;
                    }

                    dragControl.TargetBone = bone;
                    hitDistance            = match.Distance;
                    Vector3 hitPosition = cameraRay.Direction * hitDistance + cameraRay.Origin;
                    dragControl.LinearMotor.Offset         = (hitPosition - bone.Owner.Translation).toBepuVec3();
                    dragControl.LinearMotor.TargetPosition = hitPosition.toBepuVec3();
                    ikScene.addExternalControl(dragControl);
                    poseStartPosition = new MusclePosition(true);
                    currentHandler    = match.PoseableIdentifier.PoseHandler;
                    currentHandler.posingStarted(activeModes);

                    return(true);
                }
            }
            return(false);
        }
コード例 #20
0
        public void GetHashCode_SameForEqual()
        {
            var a = new Ray3(new Vector3(1, 2, 3), Vector3.UnitY);
            var b = new Ray3(new Vector3(1, 2, 3), Vector3.UnitY);

            Assert.AreEqual(a.GetHashCode(), b.GetHashCode());
        }
コード例 #21
0
        public static Pair <bool, float> intersects(Ray3 ray, Vector3 a, Vector3 b, Vector3 c, bool positiveSide, bool negativeSide)
        {
            float distance;
            bool  intersect = Math_intersectsRayPoly(ray, a, b, c, positiveSide, negativeSide, out distance);

            return(new Pair <bool, float>(intersect, distance));
        }
コード例 #22
0
 private IEnumerable <Pair <Vector3, BuildingWallSegment> > Intersect(Ray3 ray)
 {
     return(wallSegments
            .Select(x => new Pair <Vector3?, BuildingWallSegment>(Intersects(ray, x), x))
            .Where(x => x.First.HasValue)
            .Select(x => new Pair <Vector3, BuildingWallSegment>(x.First.Value, x.Second)));
 }
コード例 #23
0
        public override Color Sample(Ray3 ray, LightSample lightSample, Vector3 normal, Vector3 position, Vector2 textureCoordinates = null)
        {
            double  NdotL       = normal ^ lightSample.Vector;
            Vector3 H           = (lightSample.Vector - ray.Direction).Normalize();
            double  NdotH       = normal ^ H;
            Color   ambientTerm = ambientColor;

            if (textureCoordinates != null && ambientTexture != null)
            {
                ambientTerm = ambientTexture.GetColor(textureCoordinates);
            }
            Color diffuseTerm = diffuseColor;

            if (textureCoordinates != null && diffuseTexture != null)
            {
                diffuseTerm = diffuseTexture.GetColor(textureCoordinates);
            }
            diffuseTerm = diffuseTerm * (Math.Max(NdotL, 0));
            Color specularTerm = specularColor;

            if (textureCoordinates != null && specularTexture != null)
            {
                specularTerm = specularTexture.GetColor(textureCoordinates);
            }
            specularTerm = specularColor * (Math.Pow(Math.Max(NdotH, 0), shininess));
            Color color = lightSample.Irradiance * (ambientTerm + diffuseTerm + specularTerm);

            return(color);
        }
コード例 #24
0
        public override bool OnUse(Ray3 ray, ComponentMiner componentMiner)
        {
            TerrainRaycastResult?terrainRaycastResult = componentMiner.Raycast <TerrainRaycastResult>(ray, RaycastMode.Interaction);

            if (terrainRaycastResult.HasValue && terrainRaycastResult.Value.CellFace.Face == 4)
            {
                int y = terrainRaycastResult.Value.CellFace.Y;
                for (int i = terrainRaycastResult.Value.CellFace.X - 1; i <= terrainRaycastResult.Value.CellFace.X + 1; i++)
                {
                    for (int j = terrainRaycastResult.Value.CellFace.Z - 1; j <= terrainRaycastResult.Value.CellFace.Z + 1; j++)
                    {
                        int cellValue = m_subsystemTerrain.Terrain.GetCellValue(i, y, j);
                        if (Terrain.ExtractContents(cellValue) == 168)
                        {
                            int data  = SoilBlock.SetNitrogen(Terrain.ExtractData(cellValue), 3);
                            int value = Terrain.ReplaceData(cellValue, data);
                            m_subsystemTerrain.ChangeCell(i, y, j, value);
                        }
                    }
                }
                m_subsystemAudio.PlayRandomSound("Audio/Impacts/Dirt", 0.5f, 0f, new Vector3(terrainRaycastResult.Value.CellFace.X, terrainRaycastResult.Value.CellFace.Y, terrainRaycastResult.Value.CellFace.Z), 3f, autoDelay: true);
                Vector3 position = new Vector3((float)terrainRaycastResult.Value.CellFace.X + 0.5f, (float)terrainRaycastResult.Value.CellFace.Y + 1.5f, (float)terrainRaycastResult.Value.CellFace.Z + 0.5f);
                Block   block    = BlocksManager.Blocks[Terrain.ExtractContents(componentMiner.ActiveBlockValue)];
                m_subsystemParticles.AddParticleSystem(block.CreateDebrisParticleSystem(m_subsystemTerrain, position, componentMiner.ActiveBlockValue, 1.25f));
                componentMiner.RemoveActiveTool(1);
                return(true);
            }
            return(false);
        }
コード例 #25
0
ファイル: Triangle.cs プロジェクト: lijiancheng0614/RayTracer
        public IntersectResult Intersect(Ray3 ray, double maxDistance)
        {
            if (!BoundingBox.Intersect(ray, maxDistance))
            {
                return(IntersectResult.NoHit());
            }
            if (normal.SqrLength() == 0)
            {
                return(IntersectResult.NoHit());
            }
            Vector3 w0       = ray.Origin - vertices[0];
            double  x        = -normal ^ w0;
            double  y        = normal ^ ray.Direction;
            double  distance = x / y;

            if (y == 0 || distance < 0)
            {
                return(IntersectResult.NoHit());
            }
            Vector3 position = ray.GetPoint(distance);
            double  uu       = edgeAB ^ edgeAB;
            double  uv       = edgeAB ^ edgeAC;
            double  vv       = edgeAC ^ edgeAC;
            Vector3 w        = position - vertices[0];
            double  wu       = w ^ (edgeAB);
            double  wv       = w ^ (edgeAC);
            double  D        = uv * uv - uu * vv;
            double  beta     = (uv * wv - vv * wu) / D;

            if (beta < 0 || beta > 1)
            {
                return(IntersectResult.NoHit());
            }
            double gamma = (uv * wu - uu * wv) / D;

            if (gamma < 0 || beta + gamma > 1)
            {
                return(IntersectResult.NoHit());
            }
            double  alpha     = 1 - beta - gamma;
            Vector3 newNormal = normal;

            if (distance > 0 && normals != null)
            {
                Vector3 n1Interpolated = normals[0] * alpha;
                Vector3 n2Interpolated = normals[1] * beta;
                Vector3 n3Interpolated = normals[2] * gamma;
                newNormal = n1Interpolated + n2Interpolated + n3Interpolated;
            }
            IntersectResult result = new IntersectResult(this, distance, position, newNormal);

            if (textures != null)
            {
                Vector2 t1Interpolated = textures[0] * alpha;
                Vector2 t2Interpolated = textures[1] * beta;
                Vector2 t3Interpolated = textures[2] * gamma;
                result.TextureCoordinates = t1Interpolated + t2Interpolated + t3Interpolated;
            }
            return(result);
        }
コード例 #26
0
        private void OnDrawGizmos()
        {
            Ray3    ray    = CreateRay3(Ray);
            Sphere3 sphere = CreateSphere3(Sphere);

            bool            test = Intersection.TestRay3Sphere3(ref ray, ref sphere);
            Ray3Sphere3Intr info;
            bool            find = Intersection.FindRay3Sphere3(ref ray, ref sphere, out info);

            FiguresColor();
            DrawRay(ref ray);
            DrawSphere(ref sphere);

            if (find)
            {
                ResultsColor();
                if (info.IntersectionType == IntersectionTypes.Point)
                {
                    DrawPoint(info.Point0);
                }
                else if (info.IntersectionType == IntersectionTypes.Segment)
                {
                    DrawSegment(info.Point0, info.Point1);
                    DrawPoint(info.Point0);
                    DrawPoint(info.Point1);
                }
            }

            LogInfo(info.IntersectionType);
            if (test != find)
            {
                LogError("test != find");
            }
        }
コード例 #27
0
ファイル: Lambertian.cs プロジェクト: Winterfr0st/rtracer
        public ScatterRecord Scatter(Ray3 rIn, HitRecord record)
        {
            Vector3 target = record.Point + record.Normal + sampler.GenerateSample();

            return
                (new ScatterRecord(this.albedo, new Ray3(record.Point, target - record.Point)));
        }
コード例 #28
0
        // Token: 0x06000035 RID: 53 RVA: 0x00002990 File Offset: 0x00000B90
        public ICollection <int> RayQuery(Ray3 ray)
        {
            List <int> list = new List <int>();
            int        i    = 0;
            int        num  = this.quantizedAabbTreeNodes.Length;

            while (i < num)
            {
                bool flag  = this.GetAabb(i).CollideRay(ray);
                bool flag2 = this.IsDataNode(i);
                if (flag2 && flag)
                {
                    list.Add(this.GetNodeDataValue(i));
                }
                if (flag || flag2)
                {
                    i++;
                }
                else
                {
                    i += this.GetBranchNodeWidth(i);
                }
            }
            return(list);
        }
コード例 #29
0
        public override bool OnUse(Ray3 ray, ComponentMiner componentMiner)
        {
            BodyRaycastResult?bodyRaycastResult = componentMiner.Raycast <BodyRaycastResult>(ray, RaycastMode.Interaction);

            if (bodyRaycastResult.HasValue)
            {
                ComponentHealth componentHealth = bodyRaycastResult.Value.ComponentBody.Entity.FindComponent <ComponentHealth>();
                if (componentHealth == null || componentHealth.Health > 0f)
                {
                    string entityTemplateName = bodyRaycastResult.Value.ComponentBody.Entity.ValuesDictionary.DatabaseObject.Name + "_Saddled";
                    Entity entity             = DatabaseManager.CreateEntity(base.Project, entityTemplateName, throwIfNotFound: false);
                    if (entity != null)
                    {
                        ComponentBody componentBody = entity.FindComponent <ComponentBody>(throwOnError: true);
                        componentBody.Position = bodyRaycastResult.Value.ComponentBody.Position;
                        componentBody.Rotation = bodyRaycastResult.Value.ComponentBody.Rotation;
                        componentBody.Velocity = bodyRaycastResult.Value.ComponentBody.Velocity;
                        entity.FindComponent <ComponentSpawn>(throwOnError: true).SpawnDuration = 0f;
                        base.Project.RemoveEntity(bodyRaycastResult.Value.ComponentBody.Entity, disposeEntity: true);
                        base.Project.AddEntity(entity);
                        m_subsystemAudio.PlaySound("Audio/BlockPlaced", 1f, m_random.Float(-0.1f, 0.1f), ray.Position, 1f, autoDelay: true);
                        componentMiner.RemoveActiveTool(1);
                    }
                }
                return(true);
            }
            return(false);
        }
コード例 #30
0
        public ScatterRecord Scatter(Ray3 rIn, HitRecord record)
        {
            Vector3 attenuation = new Vector3(1.0, 1.0, 1.0);

            Vector3 outwardNormal;
            double  ni;
            double  nt;
            double  cosine;

            // Assumes that refractive index of material outside of this material is air i.e. 1.0
            if (rIn.Direction.Dot(record.Normal) > 0)
            {
                // Ray is going from inside the material to outside so the normal is facing the wrong
                // direction for the purpose of our refract function. So flip the normal.
                outwardNormal = -record.Normal;
                ni            = this.refractiveIndex;
                nt            = 1.0;

                /*
                 * cosine = rIn.Direction.Dot(record.Normal) / rIn.Direction.Length();
                 * cosine = Math.Sqrt(1.0 - this.refractiveIndex * this.refractiveIndex * (1.0 - cosine * cosine));
                 */

                cosine = this.refractiveIndex * rIn.Direction.Dot(record.Normal) / rIn.Direction.Length();
            }
            else
            {
                outwardNormal = record.Normal;
                ni            = 1.0;
                nt            = this.refractiveIndex;

                cosine = -(rIn.Direction.Dot(record.Normal)) / rIn.Direction.Length();
            }

            // Check if this should reflect or refract
            Vector3 refractedDir = Physics.Refract(rIn.Direction, outwardNormal, ni, nt);
            double  reflectProbability;

            if (refractedDir != null)
            {
                reflectProbability = Physics.Schlick(cosine, this.refractiveIndex);
            }
            else
            {
                reflectProbability = 1.0;
            }

            if (rng.NextDouble() < reflectProbability)
            {
                // Reflects
                Vector3 reflectedDir = Physics.Reflect(rIn.Direction, outwardNormal);
                return(new ScatterRecord(attenuation, new Ray3(record.Point, reflectedDir)));
            }
            else
            {
                // Ray is refracted
                return(new ScatterRecord(attenuation, new Ray3(record.Point, refractedDir)));
            }
        }
コード例 #31
0
        /// <summary>
        /// Creates a pick ray from a screen position
        /// </summary>
        /// <param name="x">Screen X position</param>
        /// <param name="y">Screen Y position</param>
        /// <returns>Returns world ray</returns>
        public Ray3 PickRay( int x, int y )
        {
            Matrix44 matrix = m_InvProjView;

            float width = Graphics.Renderer.Viewport.Width;
            float height = Graphics.Renderer.Viewport.Height;
            Point3 pt = new Point3( ( 2 * x / width ) - 1, ( 2 * ( height - y ) / height ) - 1, 1.0f );
            Point3 invPt = matrix.HomogenousMultiply( pt );
            Point3 camPos = Frame.Translation;
            Ray3 result = new Ray3( camPos, ( invPt - camPos ).MakeNormal( ) );

            return result;
        }
コード例 #32
0
        /// <summary>
        /// Tests for an intersection between a ray and a sphere
        /// </summary>
        public static Line3Intersection GetRayIntersection( Ray3 ray, Sphere3 sphere )
        {
            Vector3	originToCentre = ray.Origin - sphere.Centre;

            float	a0	= originToCentre.SqrLength - ( sphere.SqrRadius );
            float	a1	= ray.Direction.Dot( originToCentre );
            float	discriminant;
            Point3	intersectionPt;

            if ( a0 <= 0 )
            {
                //	1 intersection: The origin of the ray is inside the sphere
                discriminant = ( a1 * a1 ) - a0;
                float t = -a1 + Functions.Sqrt( discriminant );

                intersectionPt = ray.GetPointOnRay( t );
                return new Line3Intersection(  intersectionPt, ( intersectionPt - sphere.Centre ).MakeNormal( ), t );
            }
            if ( a1 >= 0 )
            {
                //	No intersections: Ray origin is outside the sphere, ray direction points away from the sphere
                return null;
            }

            discriminant = ( a1 * a1 ) - a0;
            if ( discriminant < 0 )
            {
                //	No intersections: Ray/sphere equation has no roots
                return null;
            }

            if ( discriminant < 0.0001f )	//	TODO: Magic number
            {
                //	1 intersection: Discriminant is close to zero - there's only root to the ray/sphere equation
                float t = -a1;
                intersectionPt = ray.GetPointOnRay( t );
                return new Line3Intersection(  intersectionPt, ( intersectionPt - sphere.Centre ).MakeNormal( ), t );
            }

            //	2 intersections: 2 roots to the ray/sphere equation. Choose the closest
            float root = Functions.Sqrt( discriminant );
            float t0 = -a1 - root;
            float t1 = -a1 + root;

            float closestT = ( t0 < t1 ) ? t0 : t1;

            intersectionPt = ray.GetPointOnRay( closestT );
            return new Line3Intersection(  intersectionPt, ( intersectionPt - sphere.Centre ).MakeNormal( ), closestT );
        }
コード例 #33
0
        /// <summary>
        /// Returns information about an intersection between a ray and a plane
        /// </summary>
        public static Line3Intersection GetRayIntersection( Ray3 ray, Plane3 plane )
        {
            float	startDot	= plane.Normal.Dot( ray.Origin );
            float	diffDot		= plane.Normal.Dot( ray.Direction );

            if ( !Utils.CloseToZero( diffDot ) )
            {
                float t = ( startDot + plane.Distance ) / -diffDot;

                if ( t >= 0 )
                {
                    Line3Intersection result = new Line3Intersection( );
                    result.IntersectedObject	= plane;
                    result.IntersectionPosition = ray.Origin + ( ray.Direction * t );
                    result.IntersectionNormal	= plane.Normal;
                    result.Distance				= t;
                    return result;
                }
            }

            return null;
        }
コード例 #34
0
        /// <summary>
        /// Gets the first intersection between a ray and the stored intersectable objects
        /// </summary>
        /// <param name="ray">Ray</param>
        /// <param name="options">Ray cast options</param>
        /// <returns>Intersection result (null if no intersection occurred)</returns>
        public Line3Intersection GetFirstIntersection( Ray3 ray, RayCastOptions options )
        {
            options = options ?? s_DefaultOptions;
            Line3Intersection closestIntersection = null;
            foreach ( IRay3Intersector intersector in m_Intersectors )
            {
                if ( !options.TestObject( intersector ) )
                {
                    continue;
                }
                Line3Intersection intersection = intersector.GetIntersection( ray );
                if ( intersection != null )
                {
                    if ( ( closestIntersection == null ) || ( closestIntersection.Distance >= intersection.Distance ) )
                    {
                        closestIntersection = intersection;
                    }
                }
            }

            return closestIntersection;
        }
コード例 #35
0
 /// <summary>
 /// Returns true if there is an intersection between the specified ray and this plane
 /// </summary>
 public bool TestIntersection( Ray3 ray )
 {
     return Intersections3.TestRayIntersection( ray, this );
 }
コード例 #36
0
 private bool GetRayPlanetAndAtmosphereIntersection( Point3 origin, Vector3 dir, out Point3 intPt )
 {
     //	TODO: AP: Optimise ray intersection code (origin is always outside inner sphere, inside outer sphere)
     Ray3 ray = new Ray3( origin, dir );
     Line3Intersection innerIntersection = Intersections3.GetRayIntersection( ray, m_InnerSphere );
     Line3Intersection outerIntersection = Intersections3.GetRayIntersection( ray, m_OuterSphere );
     if ( innerIntersection == null )
     {
         if ( outerIntersection == null )
         {
             //	This should not happen, but there may be an edge condition
             intPt = Point3.Origin;
             return false;
         }
         intPt = outerIntersection.IntersectionPosition;
         return true;
     }
     if ( ( outerIntersection == null ) || ( innerIntersection.Distance < outerIntersection.Distance ) )
     {
         intPt = innerIntersection.IntersectionPosition;
         return true;
     }
     intPt = outerIntersection.IntersectionPosition;
     return true;
 }
コード例 #37
0
 /// <summary>
 /// Checks if a ray intersects this object, returning information about the intersection if it does
 /// </summary>
 /// <param name="ray">Ray to check</param>
 /// <returns>Intersection information. If no intersection takes place, this method returns null</returns>
 public Line3Intersection GetIntersection( Ray3 ray )
 {
     Line3Intersection pick = Intersections3.GetRayIntersection( ray, m_Spinner, Vector3.YAxis );
     if ( ( pick == null ) || ( pick.IntersectionPosition.DistanceTo( m_Spinner ) > Radius ) )
     {
         return null;
     }
     pick.IntersectedObject = this;
     return pick;
 }
コード例 #38
0
 /// <summary>
 /// Returns details about the intersection between a specified ray and this plane (returns null if no intersection exists)
 /// </summary>
 public Line3Intersection GetIntersection( Ray3 ray )
 {
     return Intersections3.GetRayIntersection( ray, this );
 }
コード例 #39
0
 /// <summary>
 /// Intersects a ray with a quad
 /// </summary>
 /// <param name="ray">Ray </param>
 /// <param name="pt0">Quad corner position</param>
 /// <param name="pt1">Quad corner position</param>
 /// <param name="pt2">Quad corner position</param>
 /// <param name="pt3">Quad corner position</param>
 /// <returns>Returns intersection details, or null if there was no intersection</returns>
 public static Line3Intersection GetRayQuadIntersection( Ray3 ray, Point3 pt0, Point3 pt1, Point3 pt2, Point3 pt3 )
 {
     //	TODO: AP: This is very lazy...
     Line3Intersection intersection = GetRayTriangleIntersection( ray, pt0, pt1, pt2 );
     if ( intersection == null )
     {
         intersection = GetRayTriangleIntersection( ray, pt2, pt3, pt0 );
     }
     return intersection;
 }
コード例 #40
0
 /// <summary>
 /// Checks if a ray intersects this object
 /// </summary>
 /// <param name="ray">Ray to check</param>
 /// <returns>true if the ray intersects this object</returns>
 public bool TestIntersection( Ray3 ray )
 {
     Line3Intersection pick = Intersections3.GetRayIntersection( ray, m_Spinner, Vector3.YAxis );
     return pick == null ? false : pick.IntersectionPosition.DistanceTo( m_Spinner ) < Radius;
 }
コード例 #41
0
 /// <summary>
 /// Intersects a ray with a triangle
 /// </summary>
 public static Line3Intersection GetRayTriangleIntersection( Ray3 ray, Point3 pt0, Point3 pt1, Point3 pt2 )
 {
     return GetRayTriangleIntersection( ray, pt0, pt1, pt2, float.MaxValue );
 }
コード例 #42
0
        /// <summary>
        /// Intersects a ray with a triangle. If the intersection point is beyond a given distance from the ray origin, the intersection is rejected
        /// </summary>
        public static Line3Intersection GetRayTriangleIntersection( Ray3 ray, Point3 pt0, Point3 pt1, Point3 pt2, float maxDistance )
        {
            Vector3 uVec			= ( pt1 - pt0 );
            Vector3 vVec			= ( pt2 - pt0 );
            Vector3 nVec			= Vector3.Cross( uVec, vVec );
            float	nVecSqrLength	= nVec.SqrLength;
            if ( nVecSqrLength < 0.001f )
            {
                //	Degenerate tri - no intersection
                return null;
            }

            Vector3 w0	= ray.Origin - pt0;
            float	a	= -nVec.Dot( w0 );
            float	b	= nVec.Dot( ray.Direction );
            if ( System.Math.Abs( b ) < 0.001f )
            {
                //	Ray is parallel to the tri - reject
                return null;
            }
            float	r	= a / b;
            if ( r < 0 )
            {
                //	Ray goes away from the tri - reject
                return null;
            }

            //	Ray intersects tri plane - calculate position in tri
            Point3	pt	= ray.Origin + ray.Direction * r;

            float	uu	= uVec.Dot( uVec );
            float	uv	= uVec.Dot( vVec );
            float	vv	= vVec.Dot( vVec );
            Vector3	w	= pt - pt0;
            float	wu	= w.Dot( uVec );
            float	wv	= w.Dot( vVec );

            float	d	= ( uv * uv - uu * vv );
            float	s	= ( uv * wv - vv * wu ) / d;
            if ( s < 0 || s > 1 )
            {
                return null;
            }
            float	t	= ( uv * wu - uu * wv ) / d;
            if ( t < 0 || t > 1 )
            {
                return null;
            }

            nVec /= Functions.Sqrt( nVecSqrLength );
            return new Line3Intersection( pt, nVec, r );
        }
コード例 #43
0
        /// <summary>
        /// Tests for an intersection between a ray and a plane
        /// </summary>
        public static bool TestRayIntersection( Ray3 ray, Plane3 plane )
        {
            float	startDot	= plane.Normal.Dot( ray.Origin );
            float	diffDot		= plane.Normal.Dot( ray.Direction );

            if ( !Utils.CloseToZero( diffDot ) )
            {
                float t = ( startDot + plane.Distance ) / -diffDot;
                return ( t >= 0 );
            }

            return false;
        }
コード例 #44
0
 /// <summary>
 /// Checks if a ray intersects this object, returning information about the intersection if it does
 /// </summary>
 /// <param name="ray">Ray to check</param>
 /// <returns>Intersection information. If no intersection takes place, this method returns null</returns>
 public virtual Line3Intersection GetIntersection( Ray3 ray )
 {
     Line3Intersection pick = m_Plane.GetIntersection( ray );
     if ( ( pick == null ) || ( pick.IntersectionPosition.DistanceTo( Position ) > Radius ) )
     {
         return null;
     }
     pick.IntersectedObject = this;
     return pick;
 }
コード例 #45
0
        /// <summary>
        /// Casts a ray
        /// </summary>
        /// <param name="ray">Ray to cast</param>
        /// <param name="options">Options for determining which layers to check, objects to exclude, maximum ray length (!) etc.</param>
        /// <returns>Returns an array of all intersections</returns>
        public Line3Intersection[] GetIntersections( Ray3 ray, RayCastOptions options )
        {
            options = options ?? s_DefaultOptions;
            List< Line3Intersection > intersections = new List< Line3Intersection >( 4 );

            foreach ( IRay3Intersector intersector in m_Intersectors )
            {
                if ( !options.TestObject( intersector ) )
                {
                    continue;
                }
                Line3Intersection intersection = intersector.GetIntersection( ray );
                if ( intersection != null )
                {
                    intersections.Add( intersection );
                }
            }

            return intersections.ToArray( );
        }
コード例 #46
0
    bool Ray3DToPlane(Ray3 ray, Plane plane, ref Vector3 result)
    {
        float parallelResult = Vector3.Dot(ray.dir, plane.Normal);

        if (Math.Abs(parallelResult) > 0)
        {
            float d = Vector3.Dot((plane.pos - ray.pos), plane.Normal);
            d /= parallelResult;
            result = ray.pos + d * ray.dir;
            return true;
        }
        return false;
    }
コード例 #47
0
        /// <summary>
        /// Returns information about an intersection between a ray, and a plane defined by a point and a normal
        /// </summary>
        public static Line3Intersection GetRayIntersection( Ray3 ray, Point3 pt, Vector3 vec )
        {
            float	startDot	= vec.Dot( ray.Origin );
            float	diffDot		= vec.Dot( ray.Direction );

            if ( !Utils.CloseToZero( diffDot ) )
            {
                float d = -vec.Dot( pt );
                float t = ( startDot + d ) / -diffDot;

                if ( t >= 0 )
                {
                    Line3Intersection result = new Line3Intersection( );
                    result.IntersectedObject	= null;
                    result.IntersectionPosition = ray.Origin + ( ray.Direction * t );
                    result.IntersectionNormal	= vec;
                    result.Distance				= t;
                    return result;
                }
            }

            return null;
        }
コード例 #48
0
 /// <summary>
 /// Checks if a ray intersects this object
 /// </summary>
 /// <param name="ray">Ray to check</param>
 /// <returns>true if the ray intersects this object</returns>
 public virtual bool TestIntersection( Ray3 ray )
 {
     Line3Intersection pick = m_Plane.GetIntersection( ray );
     return pick == null ? false : pick.IntersectionPosition.DistanceTo( Position ) > Radius;
 }
コード例 #49
0
 /// <summary>
 /// Gets the intersection between the base intersector and a ray
 /// </summary>
 /// <param name="ray">Ray to test</param>
 /// <returns>Intersection details, or null if no intersection occurred</returns>
 public Line3Intersection GetIntersection( Ray3 ray )
 {
     return m_Intersector.GetIntersection( ray );
 }
コード例 #50
0
 /// <summary>
 /// Tests if the base intersector intersects the specified ray
 /// </summary>
 /// <param name="ray">Ray to test</param>
 /// <returns>True if ray is intersected</returns>
 public bool TestIntersection( Ray3 ray )
 {
     return m_Intersector.TestIntersection( ray );
 }
コード例 #51
0
        /// <summary>
        /// Makes a 3d ray in world space from a screen space position
        /// </summary>
        public override Ray3 PickRay( int x, int y )
        {
            double[]	modelMatrix			= new double[ 16 ];
            double[]	projectionMatrix	= new double[ 16 ];
            int[]		viewport			= new int[ 4 ];

            double outX;
            double outY;
            double outZ;

            Gl.glGetDoublev( Gl.GL_MODELVIEW_MATRIX, modelMatrix );
            Gl.glGetDoublev( Gl.GL_PROJECTION_MATRIX, projectionMatrix );
            Gl.glGetIntegerv( Gl.GL_VIEWPORT, viewport );

            //	Correct windows screen space into openGL screen space
            double inX = x;
            double inY = ( double )viewport[ 3 ] - y;

            //	TODO:This isn't right - the pick ray origin should be the camera origin
            Glu.gluUnProject( inX, inY, 0, modelMatrix, projectionMatrix, viewport, out outX, out outY, out outZ );

            Ray3 result = new Ray3( );
            result.Origin.Set( ( float )outX, ( float )outY, ( float )outZ );

            Glu.gluUnProject( inX, inY, 1, modelMatrix, projectionMatrix, viewport, out outX, out outY, out outZ );
            result.Direction = new Vector3( ( float )outX, ( float )outY, ( float )outZ );

            result.Direction.Normalise( );

            return result;
        }