示例#1
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);
            }
        }
示例#2
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);
        }
示例#3
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);
        }
示例#4
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;
		}
示例#5
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;
		}
示例#6
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;
			}
		}
示例#7
0
		public TraceResult RotationModel(Vector3 start, idRotation rotation, idClipModel model, Matrix traceModelAxis, ContentFlags contentMask, int modelHandle, Vector3 modelOrigin, Matrix modelAxis)
		{
			idConsole.Warning("TODO: idClip.RotationModel");
			// TODO: idTraceModel traceModel = TraceModelForClipModel(model);

			_rotationCount++;

			// TODO: return idR.CollisionModelManager.Rotation(start, rotation, traceModel, traceModelAxis, contentMask, modelHandle, modelOrigin, modelAxis);
			return new TraceResult();
		}
示例#8
0
		public bool Rotation(out TraceResult result, Vector3 start, idRotation rotation, idClipModel model, Matrix traceModelAxis, ContentFlags contentMask, idEntity passEntity)
		{
			idConsole.Warning("TODO: idClip.Rotation");
			/*idTraceModel traceModel = TraceModelForClipModel(model);
			idBounds traceBounds = new idBounds();
			TraceResult traceResult;

			if((passEntity == null) || (passEntity.Index != idR.EntityIndexWorld))
			{
				// test world
				_rotationCount++;

				// TODO: NEED ENGINE SOURCE idR.CollisionModelManager.Rotation(out result, start, rotation, traceModel, traceModelAxis, contentMask, 0, Vector3.Zero, Matrix.Identity);
				result.ContactInformation.EntityIndex = (result.Fraction != 1.0f) ? idR.EntityIndexWorld : idR.EntityIndexNone;

				if(result.Fraction == 0.0f)
				{
					return true; // blocked immediately by the world
				}
			}
			else
			{
				result = new TraceResult();
				result.Fraction = 1.0f;
				result.EndPosition = start;
				result.EndAxis = traceModelAxis * rotation.ToMatrix();
			}

			if(traceModel == null)
			{
				traceBounds = idBounds.FromPointRotation(start, rotation);
			}
			else
			{
				traceBounds = idBounds.FromBoundsRotation(traceModel.Bounds, start, traceModelAxis, rotation);
			}

			idClipModel[] clipModelList = GetTraceClipModels(traceBounds, contentMask, passEntity);

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

				if(touch.RenderModelHandle != -1)
				{
					continue;
				}

				_rotationCount++;
				// TODO: traceResult = idR.CollisionModelManager.Rotation(start, rotation, traceModel, traceModelAxis, contentMask, touch.Handle, touch.Origin, touch.Axis);

				if(traceResult.Fraction < result.Fraction)
				{
					result = traceResult;
					result.ContactInformation.EntityIndex = touch.Entity.Index;
					result.ContactInformation.ID = touch.ID;

					if(result.Fraction == 0.0f)
					{
						break;
					}
				}
			}

			return (result.Fraction < 1.0f);*/
			result = new TraceResult();
			return false;
		}