Пример #1
0
        /// <summary>
        /// Collides a ray against the world and returns the name of the
        /// first model the ray collided with.
        /// </summary>
        /// <param name="origin">The origin of the ray.</param>
        /// <param name="direction">The direction of the ray.</param>
        /// <param name="length">The length of the ray.</param>
        /// <returns>The name of the model, or null if no collision occured.</returns>
        public static string GetCollisionModel(Math.Vector3 origin, Math.Vector3 direction, float length)
        {
            float distance;

            foreach (SceneModel model in _models)
            {
                if (model.Visible && model.Model.CollideRay(Math.Vector3.Zero, origin, direction, length, out distance))
                {
                    return(model.Model.NameWithoutExtension);
                }
            }

            foreach (Game.Actor actor in _actors)
            {
                if (actor.CollideRay(origin, direction, length, out distance))
                {
                    return(actor.ModelName);
                }
            }

            Graphics.BspSurface surface;
            if (_currentRoom != null && _currentRoom.CollideRayWithSurfaces(origin, direction, length, out surface) == true)
            {
                return(_currentRoom.GetModelName(surface.modelIndex));
            }

            return(null);
        }
Пример #2
0
        public static void renderRadiosityCallback(Radiosity.HemicubeRenderType type,
                                                   int viewportX, int viewportY, int viewportWidth, int viewportHeight,
                                                   float eyeX, float eyeY, float eyeZ,
                                                   float directionX, float directionY, float directionZ,
                                                   float upX, float upY, float upZ)
        {
            Graphics.RendererManager.CurrentRenderer.Viewport = new Graphics.Viewport(viewportX, viewportY, viewportWidth, viewportHeight);

            Graphics.Camera c       = null;
            bool            zNegOne = (Graphics.RendererManager.CurrentRenderer.ZClipMode == Gk3Main.Graphics.ZClipMode.NegativeOne);

            const float near = 2.0f;

            Math.Vector3 position  = new Math.Vector3(eyeX, eyeY, eyeZ);
            Math.Vector3 direction = new Math.Vector3(directionX, directionY, directionZ);

            if (type == Radiosity.HemicubeRenderType.Front)
            {
                c = new Graphics.Camera(90.0f * 0.0174532925f, 1.0f, near, 1000.0f, zNegOne);
            }
            else if (type == Radiosity.HemicubeRenderType.Top)
            {
                Math.Matrix projection = Math.Matrix.PerspectiveOffCenter(-near, near, -near, 0, near, 1000.0f, zNegOne);
                c = new Graphics.Camera(projection);
            }
            else if (type == Radiosity.HemicubeRenderType.Bottom)
            {
                Math.Matrix projection = Math.Matrix.PerspectiveOffCenter(-near, near, 0, near, near, 1000.0f, zNegOne);
                c = new Graphics.Camera(projection);
            }
            else if (type == Radiosity.HemicubeRenderType.Left)
            {
                Math.Matrix projection = Math.Matrix.PerspectiveOffCenter(0, near, -near, near, near, 1000.0f, zNegOne);
                c = new Graphics.Camera(projection);
            }
            else if (type == Radiosity.HemicubeRenderType.Right)
            {
                Math.Matrix projection = Math.Matrix.PerspectiveOffCenter(-near, 0, -near, near, near, 1000.0f, zNegOne);
                c = new Graphics.Camera(projection);
            }

            c.LookAt(new Math.Vector3(eyeX, eyeY, eyeZ), new Math.Vector3(directionX, directionY, directionZ), new Math.Vector3(upX, upY, upZ));

            if (_currentSkybox != null)
            {
                _currentSkybox.Render(c);
            }
            _currentRoom.Render(c, _currentLightmaps, true);

            // add any omni lights
            foreach (OmniInfo omni in _omniLightInfo)
            {
                Graphics.BillboardManager.AddBillboard(omni.Info.Position, omni.Info.Radius, omni.Info.Radius, omni.MemTex, omni.AlphaMask);
            }

            // render any billboards
            Graphics.BillboardManager.RenderBillboardsWithAlpha(c);
        }
Пример #3
0
        public static void AddActor(string modelName, string noun, Math.Vector3 position, float heading, bool isEgo)
        {
            Game.Actor actor = new Game.Actor(_sceneContentManager, modelName, noun, isEgo);
            actor.Position    = position;
            actor.FacingAngle = heading;

            _actors.Add(actor);

            actor.LoadClothing(_sceneContentManager);
        }
Пример #4
0
        private static Graphics.SkyBox loadSkybox(Game.ScnResource scn, bool addSun)
        {
            if (string.IsNullOrEmpty(scn.SkyboxLeft) == false &&
                string.IsNullOrEmpty(scn.SkyboxRight) == false &&
                string.IsNullOrEmpty(scn.SkyboxFront) == false &&
                string.IsNullOrEmpty(scn.SkyboxBack) == false &&
                string.IsNullOrEmpty(scn.SkyboxUp) == false &&
                string.IsNullOrEmpty(scn.SkyboxDown) == false)
            {
                System.IO.Stream frontStream = FileSystem.Open(scn.SkyboxFront + ".BMP");
                System.IO.Stream backStream  = FileSystem.Open(scn.SkyboxBack + ".BMP");
                System.IO.Stream leftStream  = FileSystem.Open(scn.SkyboxLeft + ".BMP");
                System.IO.Stream rightStream = FileSystem.Open(scn.SkyboxRight + ".BMP");
                System.IO.Stream upStream    = FileSystem.Open(scn.SkyboxUp + ".BMP");

                Graphics.BitmapSurface fronts = new Graphics.BitmapSurface(frontStream);
                Graphics.BitmapSurface backs  = new Graphics.BitmapSurface(backStream);
                Graphics.BitmapSurface lefts  = new Graphics.BitmapSurface(leftStream);
                Graphics.BitmapSurface rights = new Graphics.BitmapSurface(rightStream);
                Graphics.BitmapSurface ups    = new Graphics.BitmapSurface(upStream);
                Graphics.BitmapSurface downs  = null;

                try
                {
                    System.IO.Stream downStream = FileSystem.Open(scn.SkyboxDown + ".BMP");
                    downs = new Graphics.BitmapSurface(downStream);
                    downStream.Close();
                }
                catch (System.IO.FileNotFoundException)
                {
                    downs = lefts;
                }

                frontStream.Close();
                backStream.Close();
                leftStream.Close();
                rightStream.Close();
                upStream.Close();

                Gk3Main.Graphics.SkyBox sb = new Gk3Main.Graphics.SkyBox(scn.Name + "_skybox", fronts, backs,
                                                                         lefts, rights, ups, downs, Utils.DegreesToRadians(scn.SkyboxAzimuth));

                if (addSun)
                {
                    Math.Vector3 dir = new Math.Vector3(0.4873306f, -0.8727542f, 0.02844055f);
                    //Gk3Main.Graphics.SkyBox.AddSun(dir, new Math.Vector3(1.0f, 0, 0), 0.025f, fronts, backs, lefts, rights, ups, false);

                    sb.AddSun(dir, new Math.Vector3(1.0f, 0, 0), false);
                }

                return(sb);
            }

            return(null);
        }
Пример #5
0
        public static bool TestRaySphereCollision(Math.Vector3 origin,
                                                  Math.Vector3 direction, Math.Vector3 spherePosition, float radius, out float distance)
        {
            Math.Vector3 sphereToOrigin = origin - spherePosition;
            float        b = 2 * (sphereToOrigin.Dot(direction));
            float        c = sphereToOrigin.Dot(sphereToOrigin) - radius * radius;

            float d = b * b - 4 * c;

            if (d < 0)
            {
                distance = 0;
                return(false);
            }

            float dsqrt = (float)System.Math.Sqrt(d);
            float q;

            if (b < 0)
            {
                q = (-b - dsqrt) * 0.5f;
            }
            else
            {
                q = (-b + dsqrt) * 0.5f;
            }

            float t0 = q;
            float t1 = c / q;

            if (t0 > t1)
            {
                float tmp = t0;
                t0 = t1;
                t1 = tmp;
            }

            if (t1 < 0)
            {
                distance = 0;
                return(false);
            }

            if (t0 < 0)
            {
                distance = t1;
            }
            else
            {
                distance = t1;
            }

            return(true);
        }
Пример #6
0
 public static void SetActorPosition(string noun, Math.Vector3 position, float heading)
 {
     foreach (Actor actor in _actors)
     {
         if (actor.Noun.Equals(noun, StringComparison.OrdinalIgnoreCase))
         {
             actor.Position    = position;
             actor.FacingAngle = heading;
             actor.Model.ClearAnimatedTransforms();
             break;
         }
     }
 }
Пример #7
0
        public static bool TestRayAABBCollision(Math.Vector3 aabbOffset, Math.Vector3 origin,
                                                Math.Vector3 direction, float[] aabb, out float distance)
        {
            // based on http://www.cs.utah.edu/~awilliam/box/box.pdf

            distance = float.MinValue;
            Math.Vector3 inverseDirection = new Math.Vector3(1.0f / direction.X, 1.0f / direction.Y, 1.0f / direction.Z);

            int signX = inverseDirection.X < 0 ? 1 : 0;
            int signY = inverseDirection.Y < 0 ? 1 : 0;
            int signZ = inverseDirection.Z < 0 ? 1 : 0;

            float tmin  = (aabb[signX * 3 + 0] + aabbOffset.X - origin.X) * inverseDirection.X;
            float tmax  = (aabb[(1 - signX) * 3 + 0] + aabbOffset.X - origin.X) * inverseDirection.X;
            float tymin = (aabb[signY * 3 + 1] + aabbOffset.Y - origin.Y) * inverseDirection.Y;
            float tymax = (aabb[(1 - signY) * 3 + 1] + aabbOffset.Y - origin.Y) * inverseDirection.Y;

            if (tmin > tymax || tymin > tmax)
            {
                return(false);
            }
            if (tymin > tmin)
            {
                tmin = tymin;
            }
            if (tymax < tmax)
            {
                tmax = tymax;
            }

            float tzmin = (aabb[signZ * 3 + 2] + aabbOffset.Z - origin.Z) * inverseDirection.Z;
            float tzmax = (aabb[(1 - signZ) * 3 + 2] + aabbOffset.Z - origin.Z) * inverseDirection.Z;

            if (tmin > tzmax || tzmin > tmax)
            {
                return(false);
            }

            if (tzmin > tmin)
            {
                tmin = tzmin;
            }
            if (tzmax < tmax)
            {
                tmax = tzmax;
            }

            distance = tmin;
            return(tmin > 0);
        }
Пример #8
0
        public static bool TestRayTriangleCollision(Math.Vector3 origin,
                                                    Math.Vector3 direction, Math.Vector3 v1,
                                                    Math.Vector3 v2, Math.Vector3 v3,
                                                    out float distance, out Math.Vector3?collisionPoint)
        {
            distance       = 0;
            collisionPoint = null;

            const float EPSILON = 0.00001f;

            Math.Vector3 edge1 = v2 - v1;
            Math.Vector3 edge2 = v3 - v1;

            Math.Vector3 pvec = direction.Cross(edge2);

            float det = edge1.Dot(pvec);

            if (det > -EPSILON && det < EPSILON)
            {
                return(false);
            }

            float inv_det = 1.0f / det;

            Math.Vector3 tvec = origin - v1;

            float u = tvec.Dot(pvec) * inv_det;

            if (u < 0.0f || u > 1.0f)
            {
                return(false);
            }

            Math.Vector3 qvec = tvec.Cross(edge1);

            float v = direction.Dot(qvec) * inv_det;

            if (v < 0.0f || u + v > 1.0f)
            {
                return(false);
            }

            // pack up the results
            distance = edge2.Dot(qvec) * inv_det;

            collisionPoint = v1 + edge1 * u + edge2 * v;

            return(true);
        }