Beispiel #1
0
        /// <summary>
        /// Most tight bounds for the rotational movement of the given bounds.
        /// </summary>
        /// <param name="idBounds"></param>
        /// <returns></returns>
        public static idBounds FromBoundsRotation(idBounds bounds, Vector3 origin, Matrix axis, idRotation rotation)
        {
            idBounds result = idBounds.Zero;
            Vector3  point  = Vector3.Zero;
            float    radius;

            if (idMath.Abs(rotation.Angle) < 180.0f)
            {
                result = BoundsForPointRotation(Vector3.Transform(bounds.Min, axis) + origin, rotation);
                point  = Vector3.Zero;

                for (int i = 1; i < 8; i++)
                {
                    point.X = (((i ^ (i >> 1)) & 1) == 0) ? bounds.Min.X : bounds.Max.X;
                    point.Y = (((i >> 1) & 1) == 0) ? bounds.Min.Y : bounds.Max.Y;
                    point.Z = (((i >> 2) & 1) == 0) ? bounds.Min.Z : bounds.Max.Z;

                    result += BoundsForPointRotation(Vector3.Transform(point, axis) + origin, rotation);
                }
            }
            else
            {
                point  = (bounds.Max - bounds.Min) * 0.5f;
                radius = (bounds.Max - point).Length() + (point - rotation.Origin).Length();

                result     = new idBounds();
                result.Min = new Vector3(-radius, -radius, -radius);
                result.Max = new Vector3(radius, radius, radius);
            }

            return(result);
        }
Beispiel #2
0
        /// <summary>
        /// A fast, conservative center-to-corner culling test.
        /// </summary>
        /// <param name="bounds"></param>
        /// <param name="modelMatrix"></param>
        /// <param name="planeCount"></param>
        /// <param name="planes"></param>
        /// <returns>Returns true if the box is outside the given global frustum, (positive sides are out).</returns>
        public static bool RadiusCullLocalBox(idBounds bounds, Matrix modelMatrix, int planeCount, Plane[] planes)
        {
            if (idE.CvarSystem.GetInteger("r_useCulling") == 0)
            {
                return(false);
            }

            // transform the surface bounds into world space
            Vector3 localOrigin = (bounds.Min + bounds.Max) * 0.5f;
            Vector3 worldOrigin;

            LocalPointToGlobal(modelMatrix, localOrigin, out worldOrigin);

            float worldRadius = (bounds.Min - localOrigin).Length(); // FIXME: won't be correct for scaled objects

            for (int i = 0; i < planeCount; i++)
            {
                Plane frust = planes[i];
                float d     = frust.Distance(worldOrigin);

                if (d > worldRadius)
                {
                    return(true); // culled
                }
            }

            return(false);               // no culled
        }
Beispiel #3
0
        /// <summary>
        /// Performs quick test before expensive test.
        /// </summary>
        /// <param name="bounds"></param>
        /// <param name="modelMAtrix"></param>
        /// <param name="planeCount"></param>
        /// <param name="planes"></param>
        /// <returns>Returns true if the box is outside the given global frustum, (positive sides are out).</returns>
        public static bool CullLocalBox(idBounds bounds, Matrix modelMatrix, int planeCount, Plane[] planes)
        {
            if (RadiusCullLocalBox(bounds, modelMatrix, planeCount, planes) == true)
            {
                return(true);
            }

            return(CornerCullLocalBox(bounds, modelMatrix, planeCount, planes));
        }
Beispiel #4
0
        public static idBounds operator +(idBounds a, idBounds b)
        {
            idBounds newBounds = new idBounds();

            newBounds.AddBounds(a);
            newBounds.AddBounds(b);

            return(newBounds);
        }
Beispiel #5
0
        public override bool Equals(object obj)
        {
            // FIXME: this is going to do boxing isn't it?  check for performance.
            if (obj is idBounds)
            {
                idBounds b = (idBounds)obj;

                return((this.Min == b.Min) && (this.Max == b.Max));
            }

            return(base.Equals(obj));
        }
Beispiel #6
0
        /// <summary>
        /// Tests all corners against the frustum.
        /// </summary>
        /// <remarks>
        /// Can still generate a few false positives when the box is outside a corner.
        /// </remarks>
        /// <param name="bounds"></param>
        /// <param name="modelMatrix"></param>
        /// <param name="planeCount"></param>
        /// <param name="planes"></param>
        /// <returns>Returns true if the box is outside the given global frustum, (positive sides are out).</returns>
        public static bool CornerCullLocalBox(idBounds bounds, Matrix modelMatrix, int planeCount, Plane[] planes)
        {
            // we can disable box culling for experimental timing purposes
            if (idE.CvarSystem.GetInteger("r_useCulling") < 2)
            {
                return(false);
            }

            Vector3 v = Vector3.Zero;

            Vector3[] transformed = new Vector3[8];
            float[]   distances = new float[8];
            int       i, j;

            // transform into world space
            for (i = 0; i < 8; i++)
            {
                v.X = ((i & 1) == 0) ? bounds.Min.X : bounds.Max.X;
                v.Y = (((i >> 1) & 1) == 0) ? bounds.Min.Y : bounds.Max.Y;
                v.Z = (((i >> 2) & 1) == 0) ? bounds.Min.Z : bounds.Max.Z;

                LocalPointToGlobal(modelMatrix, v, out transformed[i]);
            }

            // check against frustum planes
            for (i = 0; i < planeCount; i++)
            {
                Plane frust = planes[i];

                for (j = 0; j < 8; j++)
                {
                    distances[j] = frust.Distance(transformed[j]);

                    if (distances[j] < 0)
                    {
                        break;
                    }
                }

                if (j == 8)
                {
                    // all points were behind one of the planes
                    // TODO: tr.pc.c_box_cull_out++;
                    return(true);
                }
            }

            // TODO: tr.pc.c_box_cull_in++;

            return(false);               // not culled
        }
Beispiel #7
0
        /// <summary>
        /// Most tight bounds for the rotational movement of the given point.
        /// </summary>
        /// <param name="point"></param>
        /// <param name="rotation"></param>
        /// <returns></returns>
        public static idBounds FromPointRotation(Vector3 point, idRotation rotation)
        {
            if (idMath.Abs(rotation.Angle) < 180.0f)
            {
                return(BoundsForPointRotation(point, rotation));
            }
            else
            {
                float radius = (point - rotation.Origin).Length();

                // FIXME: these bounds are usually way larger
                idBounds result = new idBounds();
                result.Min = new Vector3(-radius, -radius, -radius);
                result.Max = new Vector3(radius, radius, radius);

                return(result);
            }
        }
Beispiel #8
0
        public static idBounds FromTransformedBounds(idBounds bounds, Vector3 origin, Matrix axis)
        {
            Vector3 center         = (bounds.Min + bounds.Max) * 0.5f;
            Vector3 extents        = bounds.Max - center;
            Vector3 rotatedExtents = Vector3.Zero;

            rotatedExtents.X = idMath.Abs(extents.X * axis.M11) + idMath.Abs(extents.Y * axis.M21) + idMath.Abs(extents.Y * axis.M31);
            rotatedExtents.Y = idMath.Abs(extents.X * axis.M12) + idMath.Abs(extents.Y * axis.M22) + idMath.Abs(extents.Y * axis.M32);
            rotatedExtents.Z = idMath.Abs(extents.X * axis.M13) + idMath.Abs(extents.Y * axis.M23) + idMath.Abs(extents.Y * axis.M33);

            center = origin + Vector3.Transform(center, axis);

            idBounds result = new idBounds();

            result.Min = center - rotatedExtents;
            result.Max = center + rotatedExtents;

            return(result);
        }
Beispiel #9
0
        public bool AddBounds(idBounds b)
        {
            bool expanded = false;

            if (b.Min.X < this.Min.X)
            {
                this.Min.X = b.Min.X;
                expanded   = true;
            }

            if (b.Min.Y < this.Min.Y)
            {
                this.Min.Y = b.Min.Y;
                expanded   = true;
            }

            if (b.Min.Z < this.Min.Z)
            {
                this.Min.Z = b.Min.Z;
                expanded   = true;
            }

            if (b.Max.X > this.Max.X)
            {
                this.Max.X = b.Max.X;
                expanded   = true;
            }

            if (b.Max.Y > this.Max.Y)
            {
                this.Max.Y = b.Max.Y;
                expanded   = true;
            }

            if (b.Max.Z > this.Max.Z)
            {
                this.Max.Z = b.Max.Z;
                expanded   = true;
            }

            return(expanded);
        }
Beispiel #10
0
        /// <summary>
        /// Most tight bounds for the translational movement of the given bounds.
        /// </summary>
        /// <param name="origin"></param>
        /// <param name="axis"></param>
        /// <param name="translation"></param>
        /// <returns></returns>
        public static idBounds FromBoundsTranslation(idBounds bounds, Vector3 origin, Matrix axis, Vector3 translation)
        {
            idBounds result;

            if (axis != Matrix.Identity)
            {
                result = FromTransformedBounds(bounds, origin, axis);
            }
            else
            {
                result = new idBounds(bounds.Min + origin, bounds.Max + origin);
            }

            if (translation.X < 0.0f)
            {
                bounds.Min.X += translation.X;
            }
            else
            {
                bounds.Max.X += translation.X;
            }

            if (translation.Y < 0.0f)
            {
                bounds.Min.Y += translation.Y;
            }
            else
            {
                bounds.Max.Y += translation.Y;
            }

            if (translation.Z < 0.0f)
            {
                bounds.Min.Z += translation.Z;
            }
            else
            {
                bounds.Max.Z += translation.Z;
            }

            return(bounds);
        }
Beispiel #11
0
        /// <summary>
        /// Most tight bounds for the translational movement of the given point.
        /// </summary>
        /// <param name="point"></param>
        /// <param name="translation"></param>
        /// <returns></returns>
        public static idBounds FromPointTranslation(Vector3 point, Vector3 translation)
        {
            idBounds result = new idBounds();

            if (translation.X < 0.0f)
            {
                result.Min.X = point.X + translation.X;
                result.Max.X = point.X;
            }
            else
            {
                result.Min.X = point.X;
                result.Max.X = point.X + translation.X;
            }

            if (translation.Y < 0.0f)
            {
                result.Min.Y = point.Y + translation.Y;
                result.Max.Y = point.Y;
            }
            else
            {
                result.Min.Y = point.Y;
                result.Max.Y = point.Y + translation.Y;
            }

            if (translation.Z < 0.0f)
            {
                result.Min.Z = point.Z + translation.Z;
                result.Max.Z = point.Z;
            }
            else
            {
                result.Min.Z = point.Z;
                result.Max.Z = point.Z + translation.Z;
            }

            return(result);
        }
Beispiel #12
0
		/// <summary>
		/// Most tight bounds for the translational movement of the given bounds.
		/// </summary>
		/// <param name="origin"></param>
		/// <param name="axis"></param>
		/// <param name="translation"></param>
		/// <returns></returns>
		public static idBounds FromBoundsTranslation(idBounds bounds, Vector3 origin, Matrix axis, Vector3 translation)
		{
			idBounds result;

			if(axis != Matrix.Identity)
			{
				result = FromTransformedBounds(bounds, origin, axis);
			}
			else
			{
				result = new idBounds(bounds.Min + origin, bounds.Max + origin);
			}

			if(translation.X < 0.0f)
			{
				bounds.Min.X += translation.X;
			}
			else
			{
				bounds.Max.X += translation.X;
			}

			if(translation.Y < 0.0f)
			{
				bounds.Min.Y += translation.Y;
			}
			else
			{
				bounds.Max.Y += translation.Y;
			}

			if(translation.Z < 0.0f)
			{
				bounds.Min.Z += translation.Z;
			}
			else
			{
				bounds.Max.Z += translation.Z;
			}

			return bounds;
		}
Beispiel #13
0
		public static idBounds operator +(idBounds a, idBounds b)
		{
			idBounds newBounds = new idBounds();
			newBounds.AddBounds(a);
			newBounds.AddBounds(b);

			return newBounds;
		}
Beispiel #14
0
		public static idBounds Expand(idBounds bounds, float d)
		{
			return new idBounds(new Vector3(bounds.Min.X - d, bounds.Min.Y - d, bounds.Min.Z - d),
				new Vector3(bounds.Max.X + d, bounds.Max.Y + d, bounds.Max.Z + d));
		}
Beispiel #15
0
		public idTraceModel(idBounds bounds, int sideCount)
		{
			SetupCylinder(bounds, sideCount);
		}
Beispiel #16
0
		public ContentFlags Contents(Vector3 start, idClipModel model, Matrix traceModelAxis, ContentFlags contentMask, idEntity passEntity)
		{
			idConsole.Warning("TODO: idClip.Contents");
			ContentFlags contents = ContentFlags.None;
			idBounds traceModelBounds = new idBounds();
			
			// TODO
			/*idTraceModel traceModel = TraceModelForClipModel(model);

			if((passEntity == null) || (passEntity.Index != idR.EntityIndexWorld))
			{
				// test world
				_contentCount++;
				// TODO: NEED ENGINE SOURCE contents = idR.CollisionModelManager.Contents(start, traceModel, traceModelAxis, contentMask, 0, Vector3.Zero, Matrix.Identity);
			}
			else
			{
				contents = ContentFlags.None;
			}

			if(traceModel == null)
			{
				traceModelBounds.Min = start;
				traceModelBounds.Max = start;
			}
			else if(traceModelAxis != Matrix.Identity)
			{
				traceModelBounds = idBounds.FromTransformedBounds(traceModel.Bounds, start, traceModelAxis);
			}
			else
			{
				traceModelBounds.Min = traceModel.Bounds.Min + start;
				traceModelBounds.Max = traceModel.Bounds.Max + start;
			}

			idClipModel[] traceModelList = GetTraceClipModels(traceModelBounds, -1, passEntity);

			foreach(idClipModel touch in traceModelList)
			{
				if(touch == null)
				{
					continue;
				}

				// no contents test with render models
				if(touch.RenderModelHandle != -1)
				{
					continue;
				}

				// if the entity does not have any contents we are looking for
				if((touch.Contents & contentMask) == ContentFlags.None)
				{
					continue;
				}

				// if the entity has no new contents flags
				if((touch.Contents & contents) == touch.Contents)
				{
					continue;
				}

				_contentCount++;

				// TODO
				/*if(idR.CollisionModelManager.Contents(start, traceModel, traceModelAxis, contentMask, touch.Handle, touch.Origin, touch.Axis) > 0)
				{
					contents |= (touch.Contents & contentMask);
				}*/
			/*}*/

			return contents;
		}
Beispiel #17
0
        public static idBounds BoundsForPointRotation(Vector3 start, idRotation rotation)
        {
            Vector3 end    = start * rotation;
            Vector3 axis   = rotation.Vector;
            Vector3 origin = rotation.Origin + axis * (axis * (start - rotation.Origin));

            float radiusSqr = (start - origin).LengthSquared();

            Vector3 v1 = Vector3.Cross(start - origin, axis);
            Vector3 v2 = Vector3.Cross(end - origin, axis);

            idBounds result = new idBounds();

            // if the derivative changes sign along this axis during the rotation from start to end.
            if (((v1.X > 0.0f) && (v2.X < 0.0f)) || ((v1.X < 0.0f) && (v2.X > 0.0f)))
            {
                if ((0.5f * (start.X + end.X) - origin.X) > 0.0f)
                {
                    result.Min.X = idMath.Min(start.X, end.X);
                    result.Max.X = origin.X + idMath.Sqrt(radiusSqr * (1.0f - axis.X * axis.X));
                }
                else
                {
                    result.Min.X = origin.X - idMath.Sqrt(radiusSqr * (1.0f - axis.X * axis.X));
                    result.Max.X = idMath.Max(start.X, end.X);
                }
            }
            else if (start.X > end.X)
            {
                result.Min.X = end.X;
                result.Max.X = start.X;
            }
            else
            {
                result.Min.X = start.X;
                result.Max.X = end.X;
            }

            if (((v1.Y > 0.0f) && (v2.Y < 0.0f)) || ((v1.Y < 0.0f) && (v2.Y > 0.0f)))
            {
                if ((0.5f * (start.Y + end.Y) - origin.Y) > 0.0f)
                {
                    result.Min.Y = idMath.Min(start.Y, end.Y);
                    result.Max.Y = origin.Y + idMath.Sqrt(radiusSqr * (1.0f - axis.Y * axis.Y));
                }
                else
                {
                    result.Min.Y = origin.Y - idMath.Sqrt(radiusSqr * (1.0f - axis.Y * axis.Y));
                    result.Max.Y = idMath.Max(start.Y, end.Y);
                }
            }
            else if (start.Y > end.Y)
            {
                result.Min.Y = end.Y;
                result.Max.Y = start.Y;
            }
            else
            {
                result.Min.Y = start.Y;
                result.Max.Y = end.Y;
            }

            if (((v1.Z > 0.0f) && (v2.Z < 0.0f)) || ((v1.Z < 0.0f) && (v2.Z > 0.0f)))
            {
                if ((0.5f * (start.Z + end.Z) - origin.Z) > 0.0f)
                {
                    result.Min.Z = idMath.Min(start.Z, end.Z);
                    result.Max.Z = origin.Z + idMath.Sqrt(radiusSqr * (1.0f - axis.Z * axis.Z));
                }
                else
                {
                    result.Min.Z = origin.Z - idMath.Sqrt(radiusSqr * (1.0f - axis.Z * axis.Z));
                    result.Max.Z = idMath.Max(start.Z, end.Z);
                }
            }
            else if (start.Z > end.Z)
            {
                result.Min.Z = end.Z;
                result.Max.Z = start.Z;
            }
            else
            {
                result.Min.Z = start.Z;
                result.Max.Z = end.Z;
            }

            return(result);
        }
Beispiel #18
0
		/// <summary>
		/// Most tight bounds for the rotational movement of the given point.
		/// </summary>
		/// <param name="point"></param>
		/// <param name="rotation"></param>
		/// <returns></returns>
		public static idBounds FromPointRotation(Vector3 point, idRotation rotation)
		{
			if(idMath.Abs(rotation.Angle) < 180.0f)
			{
				return BoundsForPointRotation(point, rotation);
			}
			else
			{
				float radius = (point - rotation.Origin).Length();

				// FIXME: these bounds are usually way larger
				idBounds result = new idBounds();
				result.Min = new Vector3(-radius, -radius, -radius);
				result.Max = new Vector3(radius, radius, radius);

				return result;
			}
		}
Beispiel #19
0
		public bool AddBounds(idBounds b)
		{
			bool expanded = false;

			if(b.Min.X < this.Min.X)
			{
				this.Min.X = b.Min.X;
				expanded = true;
			}

			if(b.Min.Y < this.Min.Y)
			{
				this.Min.Y = b.Min.Y;
				expanded = true;
			}

			if(b.Min.Z < this.Min.Z)
			{
				this.Min.Z = b.Min.Z;
				expanded = true;
			}

			if(b.Max.X > this.Max.X)
			{
				this.Max.X = b.Max.X;
				expanded = true;
			}

			if(b.Max.Y > this.Max.Y)
			{
				this.Max.Y = b.Max.Y;
				expanded = true;
			}

			if(b.Max.Z > this.Max.Z)
			{
				this.Max.Z = b.Max.Z;
				expanded = true;
			}

			return expanded;
		}
Beispiel #20
0
		/// <summary>
		/// Axial bounding box.
		/// </summary>
		/// <param name="bounds"></param>
		public idTraceModel(idBounds bounds)
		{
			InitBox();
			SetupBox(bounds);
		}
Beispiel #21
0
		public idTraceModel()
		{
			_type = TraceModelType.Invalid;
			_bounds = idBounds.Zero;

			_edges = new TraceModelEdge[0];
			_polygons = new TraceModelPolygon[0];
			_vertices = new Vector3[0];
		}
Beispiel #22
0
		public void SetupCylinder(idBounds bounds, int sideCount)
		{
			int n = sideCount;

			if(n < 3)
			{
				n = 3;
			}

			if((n * 2) > MaxVertices)
			{
				idConsole.WriteLine("WARNING: idTraceModel::SetupCylinder: too many vertices");
				n = MaxVertices / 2;
			}

			if((n * 3) > MaxEdges)
			{
				idConsole.WriteLine("WARNING: idTraceModel::SetupCylinder: too many sides");
				n = MaxEdges / 3;
			}

			if((n + 2) > MaxPolygons)
			{
				idConsole.WriteLine("WARNING: idTraceModel::SetupCylinder: too many polygons");
				n = MaxPolygons - 2;
			}

			_type = TraceModelType.Cylinder;

			_vertices = new Vector3[n * 2];
			_edges = new TraceModelEdge[n * 3];
			_polygons = new TraceModelPolygon[n + 2];

			_offset = (bounds.Min + bounds.Max) * 0.5f;

			Vector3 halfSize = bounds.Max - _offset;

			for(int i = 0; i < n; i++)
			{
				// verts
				float angle = idMath.TwoPi * i / n;

				_vertices[i].X = idMath.Cos(angle) * halfSize.X + _offset.X;
				_vertices[i].Y = idMath.Sin(angle) * halfSize.Y + _offset.Y;
				_vertices[i].Z = -halfSize.Z + _offset.Z;

				_vertices[n + i].X = _vertices[i].X;
				_vertices[n + i].Y = _vertices[i].Y;
				_vertices[n + i].Z = halfSize.Z + _offset.Z;

				// edges
				int ii = i + 1;
				int n2 = n << 1;

				_edges[ii].V[0] = i;
				_edges[ii].V[1] = ii % n;
				_edges[n + ii].V[0] = _edges[ii].V[0] + n;
				_edges[n + ii].V[1] = _edges[ii].V[1] + n;
				_edges[n2 + ii].V[0] = i;
				_edges[n2 + ii].V[1] = n + i;

				// vertical polygon edges
				_polygons[i].Edges = new int[4];
				_polygons[i].Edges[0] = ii;
				_polygons[i].Edges[1] = n2 + (ii % n) + 1;
				_polygons[i].Edges[2] = -(n + ii);
				_polygons[i].Edges[3] = -(n2 + ii);

				// bottom and top polygon edges
				_polygons[n].Edges[i] = -(n - i);
				_polygons[n + 1].Edges[i] = n + ii;
			}

			// bottom and top polygon numEdges
			_polygons[n].Edges = new int[n];
			_polygons[n + 1].Edges = new int[n];

			// polygons
			for(int i = 0; i < n; i++)
			{
				// vertical polygon plane
				_polygons[i].Normal = Vector3.Cross(_vertices[(i + 1) % n] - _vertices[i], _vertices[n + i] - _vertices[i]);
				_polygons[i].Normal.Normalize();

				// vertical polygon bounds
				_polygons[i].Bounds.Clear();
				_polygons[i].Bounds.AddPoint(_vertices[i]);
				_polygons[i].Bounds.AddPoint(_vertices[(i + 1) % n]);
				_polygons[i].Bounds.Min.Z = -halfSize.Z + _offset.Z;
				_polygons[i].Bounds.Max.Z = halfSize.Z + _offset.Z;
			}

			// bottom and top polygon plane
			_polygons[n].Normal = new Vector3(0, 0, -1.0f);
			_polygons[n].Distance = -bounds.Min.Z;
			_polygons[n + 1].Normal = new Vector3(0, 0, 1.0f);
			_polygons[n + 1].Distance = bounds.Max.Z;

			// trm bounds
			_bounds = bounds;

			// bottom and top polygon bounds
			_polygons[n].Bounds = bounds;
			_polygons[n].Bounds.Max.Z = bounds.Min.Z;
			_polygons[n + 1].Bounds = bounds;
			_polygons[n + 1].Bounds.Min.Z = bounds.Max.Z;

			// convex model
			_isConvex = true;
			
			GenerateEdgeNormals();
		}
Beispiel #23
0
		public void SetupBox(idBounds bounds)
		{
			if(_type != TraceModelType.Box)
			{
				InitBox();
			}

			// offset to center
			_offset = (bounds.Min + bounds.Max) * 0.5f;

			// set box vertices
			_vertices = new Vector3[8];

			for(int i = 0; i < 8; i++)
			{
				_vertices[i] = new Vector3(
						((i ^ (i >> 1)) == 0) ? bounds.Min.X : bounds.Max.X,
						(((i >> 1) & 1) == 0) ? bounds.Min.Y : bounds.Max.Y,
						(((i >> 2) & 1) == 0) ? bounds.Min.Z : bounds.Max.Z
					);
			}

			// set polygon plane distances
			_polygons = new TraceModelPolygon[6];
			_polygons[0].Distance = -_bounds.Min.Z;
			_polygons[1].Distance = bounds.Max.Z;
			_polygons[2].Distance = -bounds.Min.Y;
			_polygons[3].Distance = bounds.Max.X;
			_polygons[4].Distance = bounds.Max.Y;
			_polygons[5].Distance = -bounds.Min.X;

				// set polygon bounds
			for(int i = 0; i < 6; i++)
			{
				_polygons[i].Bounds = bounds;
				_polygons[i].Edges = new int[0];
			}

			_polygons[0].Bounds.Max.Z = bounds.Min.Z;
			_polygons[1].Bounds.Min.Z = bounds.Max.Z;
			_polygons[2].Bounds.Max.Y = bounds.Min.Y;
			_polygons[3].Bounds.Min.X = bounds.Max.X;
			_polygons[4].Bounds.Min.Y = bounds.Max.Y;
			_polygons[5].Bounds.Max.X = bounds.Min.X;

			_bounds = bounds;
		}
Beispiel #24
0
		/// <summary>
		/// Builds a uniformly subdivided tree for the given world size.
		/// </summary>
		/// <param name="depth"></param>
		/// <param name="bounds"></param>
		/// <param name="?"></param>
		/// <returns></returns>
		private ClipSector CreateClipSectors(int depth, idBounds bounds, ref Vector3 maxSector)
		{
			idBounds front, back;

			ClipSector anode = _clipSectors[_clipSectorCount] = new ClipSector();
			_clipSectorCount++;

			if(depth == idClip.MaxSectorDepth)
			{
				anode.Axis = -1;
				anode.Children[0] = anode.Children[1] = null;

				if((bounds.Max.X - bounds.Min.X) > maxSector.X)
				{
					maxSector.X = bounds.Max.X - bounds.Min.X;
				}

				if((bounds.Max.Y - bounds.Min.Y) > maxSector.Y)
				{
					maxSector.Y = bounds.Max.Y - bounds.Min.Y;
				}

				if((bounds.Max.Z - bounds.Min.Z) > maxSector.Z)
				{
					maxSector.Z = bounds.Max.Z - bounds.Min.Z;
				}

				return anode;
			}

			Vector3 size = bounds.Max - bounds.Min;
			front = bounds;
			back = bounds;

			if((size.X >= size.Y) && (size.X >= size.Z))
			{
				anode.Axis = 0;
				anode.Distance = 0.5f * (bounds.Max.X + bounds.Min.X);
				front.Min.X = back.Max.X = anode.Distance;
			}
			else if((size.Y >= size.X) && (size.Y >= size.Z))
			{
				anode.Axis = 1;
				anode.Distance = 0.5f * (bounds.Max.Y + bounds.Min.Y);
				front.Min.Y = back.Max.Y = anode.Distance;
			}
			else
			{
				anode.Axis = 2;
				anode.Distance = 0.5f * (bounds.Max.Z + bounds.Min.Z);
				front.Min.Z = back.Max.Z = anode.Distance;
			}

			anode.Children[0] = CreateClipSectors(depth + 1, front, ref maxSector);
			anode.Children[1] = CreateClipSectors(depth + 1, back, ref maxSector);

			return anode;
		}
Beispiel #25
0
		/// <summary>
		/// 
		/// </summary>
		/// <remarks>
		/// an ent will be excluded from testing if:
		/// cm->entity == passEntity (don't clip against the pass entity)
		/// cm->entity == passOwner (missiles don't clip with owner)
		/// cm->owner == passEntity (don't interact with your own missiles)
		/// cm->owner == passOwner (don't interact with other missiles from same owner)
		/// </remarks>
		/// <param name="bounds"></param>
		/// <param name="contentMask"></param>
		/// <param name="passEntity"></param>
		/// <returns></returns>
		private idClipModel[] GetTraceClipModels(idBounds bounds, ContentFlags contentMask, idEntity passEntity)
		{
			idConsole.Warning("TODO: idClip.GetTraceClipModels");
			// TODO
			/*int i, num;
			idClipModel	*cm;
			idEntity *passOwner;

			num = ClipModelsTouchingBounds( bounds, contentMask, clipModelList, MAX_GENTITIES );

			if ( !passEntity ) {
				return num;
			}

			if ( passEntity->GetPhysics()->GetNumClipModels() > 0 ) {
				passOwner = passEntity->GetPhysics()->GetClipModel()->GetOwner();
			} else {
				passOwner = NULL;
			}

			for ( i = 0; i < num; i++ ) {

				cm = clipModelList[i];

				// check if we should ignore this entity
				if ( cm->entity == passEntity ) {
					clipModelList[i] = NULL;			// don't clip against the pass entity
				} else if ( cm->entity == passOwner ) {
					clipModelList[i] = NULL;			// missiles don't clip with their owner
				} else if ( cm->owner ) {
					if ( cm->owner == passEntity ) {
						clipModelList[i] = NULL;		// don't clip against own missiles
					} else if ( cm->owner == passOwner ) {
						clipModelList[i] = NULL;		// don't clip against other missiles from same owner
					}
				}
			}

			return num;*/

			return null;
		}
Beispiel #26
0
		/// <summary>
		/// Most tight bounds for the translational movement of the given point.
		/// </summary>
		/// <param name="point"></param>
		/// <param name="translation"></param>
		/// <returns></returns>
		public static idBounds FromPointTranslation(Vector3 point, Vector3 translation)
		{
			idBounds result = new idBounds();

			if(translation.X < 0.0f)
			{
				result.Min.X = point.X + translation.X;
				result.Max.X = point.X;
			}
			else
			{
				result.Min.X = point.X;
				result.Max.X = point.X + translation.X;
			}

			if(translation.Y < 0.0f)
			{
				result.Min.Y = point.Y + translation.Y;
				result.Max.Y = point.Y;
			}
			else
			{
				result.Min.Y = point.Y;
				result.Max.Y = point.Y + translation.Y;
			}

			if(translation.Z < 0.0f)
			{
				result.Min.Z = point.Z + translation.Z;
				result.Max.Z = point.Z;
			}
			else
			{
				result.Min.Z = point.Z;
				result.Max.Z = point.Z + translation.Z;
			}

			return result;
		}
Beispiel #27
0
		public static idBounds FromTransformedBounds(idBounds bounds, Vector3 origin, Matrix axis)
		{
			Vector3 center = (bounds.Min + bounds.Max) * 0.5f;
			Vector3 extents = bounds.Max - center;
			Vector3 rotatedExtents = Vector3.Zero;

			rotatedExtents.X = idMath.Abs(extents.X * axis.M11) + idMath.Abs(extents.Y * axis.M21) + idMath.Abs(extents.Y * axis.M31);
			rotatedExtents.Y = idMath.Abs(extents.X * axis.M12) + idMath.Abs(extents.Y * axis.M22) + idMath.Abs(extents.Y * axis.M32);
			rotatedExtents.Z = idMath.Abs(extents.X * axis.M13) + idMath.Abs(extents.Y * axis.M23) + idMath.Abs(extents.Y * axis.M33);

			center = origin + Vector3.Transform(center, axis);

			idBounds result = new idBounds();
			result.Min = center - rotatedExtents;
			result.Max = center + rotatedExtents;

			return result;
		}
Beispiel #28
0
 public static idBounds Expand(idBounds bounds, float d)
 {
     return(new idBounds(new Vector3(bounds.Min.X - d, bounds.Min.Y - d, bounds.Min.Z - d),
                         new Vector3(bounds.Max.X + d, bounds.Max.Y + d, bounds.Max.Z + d)));
 }
Beispiel #29
0
		public static idBounds BoundsForPointRotation(Vector3 start, idRotation rotation)
		{
			Vector3 end = start * rotation;
			Vector3 axis = rotation.Vector;
			Vector3 origin = rotation.Origin + axis * (axis * (start - rotation.Origin));

			float radiusSqr = (start - origin).LengthSquared();

			Vector3 v1 = Vector3.Cross(start - origin, axis);
			Vector3 v2 = Vector3.Cross(end - origin, axis);

			idBounds result = new idBounds();

			// if the derivative changes sign along this axis during the rotation from start to end.
			if(((v1.X > 0.0f) && (v2.X < 0.0f)) || ((v1.X < 0.0f) && (v2.X > 0.0f)))
			{
				if((0.5f * (start.X + end.X) - origin.X) > 0.0f)
				{
					result.Min.X = idMath.Min(start.X, end.X);
					result.Max.X = origin.X + idMath.Sqrt(radiusSqr * (1.0f - axis.X * axis.X));
				}
				else
				{
					result.Min.X = origin.X - idMath.Sqrt(radiusSqr * (1.0f - axis.X * axis.X));
					result.Max.X = idMath.Max(start.X, end.X);
				}
			}
			else if(start.X > end.X)
			{
				result.Min.X = end.X;
				result.Max.X = start.X;
			}
			else
			{
				result.Min.X = start.X;
				result.Max.X = end.X;
			}

			if(((v1.Y > 0.0f) && (v2.Y < 0.0f)) || ((v1.Y < 0.0f) && (v2.Y > 0.0f)))
			{
				if((0.5f * (start.Y + end.Y) - origin.Y) > 0.0f)
				{
					result.Min.Y = idMath.Min(start.Y, end.Y);
					result.Max.Y = origin.Y + idMath.Sqrt(radiusSqr * (1.0f - axis.Y * axis.Y));
				}
				else
				{
					result.Min.Y = origin.Y - idMath.Sqrt(radiusSqr * (1.0f - axis.Y * axis.Y));
					result.Max.Y = idMath.Max(start.Y, end.Y);
				}
			}
			else if(start.Y > end.Y)
			{
				result.Min.Y = end.Y;
				result.Max.Y = start.Y;
			}
			else
			{
				result.Min.Y = start.Y;
				result.Max.Y = end.Y;
			}

			if(((v1.Z > 0.0f) && (v2.Z < 0.0f)) || ((v1.Z < 0.0f) && (v2.Z > 0.0f)))
			{
				if((0.5f * (start.Z + end.Z) - origin.Z) > 0.0f)
				{
					result.Min.Z = idMath.Min(start.Z, end.Z);
					result.Max.Z = origin.Z + idMath.Sqrt(radiusSqr * (1.0f - axis.Z * axis.Z));
				}
				else
				{
					result.Min.Z = origin.Z - idMath.Sqrt(radiusSqr * (1.0f - axis.Z * axis.Z));
					result.Max.Z = idMath.Max(start.Z, end.Z);
				}
			}
			else if(start.Z > end.Z)
			{
				result.Min.Z = end.Z;
				result.Max.Z = start.Z;
			}
			else
			{
				result.Min.Z = start.Z;
				result.Max.Z = end.Z;
			}

			return result;
		}
Beispiel #30
0
		/// <summary>
		/// Most tight bounds for the rotational movement of the given bounds.
		/// </summary>
		/// <param name="idBounds"></param>
		/// <returns></returns>
		public static idBounds FromBoundsRotation(idBounds bounds, Vector3 origin, Matrix axis, idRotation rotation)
		{
			idBounds result = idBounds.Zero;
			Vector3 point = Vector3.Zero;
			float radius;

			if(idMath.Abs(rotation.Angle) < 180.0f)
			{
				result = BoundsForPointRotation(Vector3.Transform(bounds.Min, axis) + origin, rotation);
				point = Vector3.Zero;

				for(int i = 1; i < 8; i++)
				{
					point.X = (((i ^ (i >> 1)) & 1) == 0) ? bounds.Min.X : bounds.Max.X;
					point.Y = (((i >> 1) & 1) == 0) ? bounds.Min.Y : bounds.Max.Y;
					point.Z = (((i >> 2) & 1) == 0) ? bounds.Min.Z : bounds.Max.Z;

					result += BoundsForPointRotation(Vector3.Transform(point, axis) + origin, rotation);
				}
			}
			else
			{
				point = (bounds.Max - bounds.Min) * 0.5f;
				radius = (bounds.Max - point).Length() + (point - rotation.Origin).Length();

				result = new idBounds();
				result.Min = new Vector3(-radius, -radius, -radius);
				result.Max = new Vector3(radius, radius, radius);
			}

			return result;
		}
Beispiel #31
0
		public void Init()
		{
			Vector3 maxSector = Vector3.Zero;

			// clear clip sectors
			_clipSectors = new ClipSector[MaxSectors];
			_clipSectorCount = 0;
			_touchCount = -1;
			
			// get world map bounds
			CollisionModel collisionModel = idR.CollisionModelManager.LoadModel("worldMap", false);

			if(collisionModel != null)
			{
				_worldBounds = collisionModel.Bounds;
			}

			// create world sectors
			CreateClipSectors(0, _worldBounds, ref maxSector);

			Vector3 size = _worldBounds.Max - _worldBounds.Min;

			idConsole.WriteLine("map bounds are ({0})", size);
			idConsole.WriteLine("max clip sector is ({0})", maxSector);

			// initialize a default clip model
			_defaultClipModel = new idClipModel();
			_defaultClipModel.LoadModel(new idTraceModel(idBounds.Expand(8)));

			// set counters to zero
			_rotationCount = 0;
			_translationCount = 0;
			_motionCount = 0;
			_renderModelTraceCount = 0;
			_contentCount = 0;
			_contactCount = 0;
		}