Exemplo n.º 1
0
        /// <summary>
        /// This is uesed to build the Z-Buffer.
        /// https://en.wikipedia.org/wiki/Z-buffering
        /// </summary>
        private void UpdateZBufferTriangles()
        {
            return;

            Vector3 myLoc = Core.Me.Location.Convert();

            if (_lastLocUpdate != Vector3.Zero && Vector3.DistanceSquared(myLoc, _lastLocUpdate) < 100 * 100)
            {
                return;
            }

            _lastLocUpdate = myLoc;

            float[]    factors   = { 1.0f, 0.8f, 0.6f, 0.5f, 0.4f, 0.3f, 0.2f, 0.1f };
            Triangle[] triangles = null;
            //commented out to allow for compiles
            //foreach (float factor in factors)
            //{
            //    Vector3 extents = new Vector3(125, 125, 40) * factor;
            //    if (GameWorld.GetTriangles((myLoc - extents).Convert(), (myLoc + extents).Convert(),
            //                                TraceLineHitFlags.DoodadRender |
            //                                TraceLineHitFlags.WmoRender |
            //                                TraceLineHitFlags.EntityRender |
            //                                TraceLineHitFlags.Terrain,
            //                                out triangles))
            //    {
            //        break;
            //    }
            //    triangles = null;
            //}

            if (triangles == null)
            {
                return;
            }

            _zBufferTriangles?.Dispose();
            _zBufferTriangles    = null;
            _numZBufferTriangles = 0;

            if (triangles.Length <= 0)
            {
                return;
            }

            _zBufferTriangles = new VertexBuffer(Device, ColoredVertex.Stride * triangles.Length * 3,
                                                 Usage.WriteOnly, ColoredVertex.Format, Pool.Default);

            ColoredVertex[] verts = new ColoredVertex[triangles.Length * 3];
            //for (int i = 0; i < triangles.Length; i++)
            //{
            //    verts[i * 3 + 0] = new ColoredVertex(triangles[i].Vertex1.Convert(), Color.White);
            //    verts[i * 3 + 1] = new ColoredVertex(triangles[i].Vertex2.Convert(), Color.White);
            //    verts[i * 3 + 2] = new ColoredVertex(triangles[i].Vertex3.Convert(), Color.White);
            //}
            _zBufferTriangles.Lock(0, ColoredVertex.Stride * triangles.Length * 3, LockFlags.None)
            .WriteRange(verts);

            _zBufferTriangles.Unlock();

            _numZBufferTriangles = triangles.Length;
        }
Exemplo n.º 2
0
        /// <summary>
        /// Creates the smallest <see cref="BoundingSphere"/> that can contain a specified list of points in 3D-space.
        /// </summary>
        /// <param name="points">List of point to create the sphere from.</param>
        /// <returns>The new <see cref="BoundingSphere"/>.</returns>
        public static BoundingSphere CreateFromPoints(IEnumerable <Vector3> points)
        {
            if (points == null)
            {
                throw new ArgumentNullException("points");
            }

            // From "Real-Time Collision Detection" (Page 89)

            Vector3 minx = new Vector3(float.MaxValue, float.MaxValue, float.MaxValue);
            Vector3 maxx = -minx;
            Vector3 miny = minx;
            Vector3 maxy = -minx;
            Vector3 minz = minx;
            Vector3 maxz = -minx;

            // Find the most extreme points along the principle axis.
            int numPoints = 0;

            foreach (Vector3 pt in points)
            {
                numPoints += 1;

                if (pt.X < minx.X)
                {
                    minx = pt;
                }
                if (pt.X > maxx.X)
                {
                    maxx = pt;
                }
                if (pt.Y < miny.Y)
                {
                    miny = pt;
                }
                if (pt.Y > maxy.Y)
                {
                    maxy = pt;
                }
                if (pt.Z < minz.Z)
                {
                    minz = pt;
                }
                if (pt.Z > maxz.Z)
                {
                    maxz = pt;
                }
            }

            if (numPoints == 0)
            {
                throw new ArgumentException(
                          "You should have at least one point in points."
                          );
            }

            float sqDistX = Vector3.DistanceSquared(maxx, minx);
            float sqDistY = Vector3.DistanceSquared(maxy, miny);
            float sqDistZ = Vector3.DistanceSquared(maxz, minz);

            // Pick the pair of most distant points.
            Vector3 min = minx;
            Vector3 max = maxx;

            if (sqDistY > sqDistX && sqDistY > sqDistZ)
            {
                max = maxy;
                min = miny;
            }
            if (sqDistZ > sqDistX && sqDistZ > sqDistY)
            {
                max = maxz;
                min = minz;
            }

            Vector3 center = (min + max) * 0.5f;
            float   radius = Vector3.Distance(max, center);

            // Test every point and expand the sphere.
            // The current bounding sphere is just a good approximation and may not enclose all points.
            // From: Mathematics for 3D Game Programming and Computer Graphics, Eric Lengyel, Third Edition.
            // Page 218
            float sqRadius = radius * radius;

            foreach (Vector3 pt in points)
            {
                Vector3 diff   = (pt - center);
                float   sqDist = diff.LengthSquared();
                if (sqDist > sqRadius)
                {
                    float   distance  = (float)Math.Sqrt(sqDist);                   // equal to diff.Length();
                    Vector3 direction = diff / distance;
                    Vector3 G         = center - radius * direction;
                    center   = (G + pt) / 2;
                    radius   = Vector3.Distance(pt, center);
                    sqRadius = radius * radius;
                }
            }

            return(new BoundingSphere(center, radius));
        }