Beispiel #1
0
        private void GetNodeBounds_R(ref idBounds bounds, CollisionModelNode node)
        {
            while (true)
            {
                foreach (CollisionModelPolygon poly in node.Polygons)
                {
                    bounds.AddPoint(poly.Bounds.Min);
                    bounds.AddPoint(poly.Bounds.Max);
                }

                foreach (CollisionModelBrush brush in node.Brushes)
                {
                    bounds.AddPoint(brush.Bounds.Min);
                    bounds.AddPoint(brush.Bounds.Max);
                }

                if (node.PlaneType == -1)
                {
                    break;
                }

                GetNodeBounds_R(ref bounds, node.Children[1]);
                node = node.Children[0];
            }
        }
Beispiel #2
0
        public void Link(idClip clip, idEntity entity, int newID, Vector3 newOrigin, Matrix newAxis, int renderModelHandle)
        {
            if (this.Disposed == true)
            {
                throw new ObjectDisposedException("idClipModel");
            }

            _entity = entity;
            _id     = newID;
            _origin = newOrigin;
            _axis   = newAxis;

            if (_renderModelHandle != -1)
            {
                _renderModelHandle = renderModelHandle;

                RenderEntityComponent renderEntity = idR.Game.RenderWorld.GetRenderEntity(renderModelHandle);

                if (renderEntity != null)
                {
                    _bounds = renderEntity.Bounds;
                }
            }

            Link(clip);
        }
Beispiel #3
0
        public idClipModel(idClipModel model)
        {
            _id    = model.ID;
            _owner = model.Owner;

            _enabled = model.Enabled;
            _entity  = model.Entity;

            _origin    = model.Origin;
            _axis      = model.Axis;
            _bounds    = model.Bounds;
            _absBounds = model.AbsoluteBounds;

            _material             = model.Material;
            _contents             = model.Contents;
            _collisionModelHandle = model.CollisionModelHandle;
            _traceModelCache      = null;

            if (model.TraceModelCache != null)
            {
                idConsole.Warning("TODO: LoadModel( *GetCachedTraceModel( model->traceModelIndex ) );");
            }

            _renderModelHandle = model.RenderModelHandle;
            _touchCount        = -1;
        }
Beispiel #4
0
        private bool InsideAllChildren(CollisionModelNode node, idBounds bounds)
        {
            if (node.PlaneType != -1)
            {
                float v  = (node.PlaneType == 0) ? bounds.Min.X : (node.PlaneType == 1) ? bounds.Min.Y : bounds.Min.Z;
                float v2 = (node.PlaneType == 0) ? bounds.Max.X : (node.PlaneType == 1) ? bounds.Max.Y : bounds.Max.Z;

                if (v >= node.PlaneDistance)
                {
                    return(false);
                }
                else if (v2 <= node.PlaneDistance)
                {
                    return(false);
                }
                else if (InsideAllChildren(node.Children[0], bounds) == false)
                {
                    return(false);
                }
                else if (InsideAllChildren(node.Children[1], bounds) == false)
                {
                    return(false);
                }
            }

            return(true);
        }
Beispiel #5
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 #6
0
        public idTraceModel()
        {
            _type   = TraceModelType.Invalid;
            _bounds = idBounds.Zero;

            _edges    = new TraceModelEdge[0];
            _polygons = new TraceModelPolygon[0];
            _vertices = new Vector3[0];
        }
Beispiel #7
0
        public virtual void SetClipBox(idBounds bounds, float density)
        {
            if (this.Disposed == true)
            {
                throw new ObjectDisposedException(this.GetType().Name);
            }

            SetClipModel(new idClipModel(new idTraceModel(bounds)), density);
        }
        public idBounds CalculateBounds(idJointMatrix[] joints)
        {
            Vertex[] verts  = new Vertex[_texCoords.Length];
            idBounds bounds = idBounds.Zero;

            TransformVertices(verts, joints);

            idHelper.MinMax(ref bounds.Min, ref bounds.Max, verts, _texCoords.Length);

            return(bounds);
        }
Beispiel #9
0
        public bool GetBounds(out idBounds bounds, int animNumber, int currentTime, int cycleCount)
        {
            if (_anims[animNumber] == null)
            {
                bounds = idBounds.Zero;
                return(false);
            }

            bounds = _anims[animNumber].GetBounds(currentTime, cycleCount);

            return(true);
        }
Beispiel #10
0
        public void LoadModel(idTraceModel traceModel)
        {
            if (this.Disposed == true)
            {
                throw new ObjectDisposedException("idClipModel");
            }

            _collisionModelHandle = 0;
            _renderModelHandle    = -1;
            _traceModelCache      = GetTraceModelCache(traceModel);

            _bounds = traceModel.Bounds;
        }
        public override void AddSurface(RenderModelSurface surface)
        {
            if (this.Disposed == true)
            {
                throw new ObjectDisposedException(this.GetType().Name);
            }

            _surfaces.Add(surface);

            if (surface.Geometry != null)
            {
                _bounds += surface.Geometry.Bounds;
            }
        }
Beispiel #12
0
        private idBounds GetNodeBounds(CollisionModelNode node)
        {
            idBounds bounds = idBounds.Zero;

            bounds.Clear();

            GetNodeBounds_R(ref bounds, node);

            if (bounds.IsCleared == true)
            {
                bounds = idBounds.Zero;
            }

            return(bounds);
        }
Beispiel #13
0
        public void SetupJoints(idJointMatrix[] joints, ref idBounds frameBounds, bool removeOriginOffset)
        {
            if (this.Disposed == true)
            {
                throw new ObjectDisposedException(this.GetType().Name);
            }

            if ((_model == null) || (_model.IsDefault == true))
            {
                joints = null;
                frameBounds.Clear();
            }

            // get the number of joints
            int count = _model.JointCount;

            if (count == 0)
            {
                idConsole.Error("model '{0}' has no joints", _model.Name);
            }

            // set up initial pose for model (with no pose, model is just a jumbled mess)
            joints = new idJointMatrix[count];
            idJointQuaternion[] pose = this.DefaultPose;

            // convert the joint quaternions to joint matrices
            idHelper.ConvertJointQuaternionsToJointMatrices(joints, pose);

            // check if we offset the model by the origin joint
            if (removeOriginOffset == true)
            {
#if VELOCITY_MOVE
                joints[0].Translation(new Vector3(_offset.X, _offset.Y + pose[0].Translation.Y, _offset.Z + pose[0].Translation.Z));
#else
                joints[0].Translation = _offset;
#endif
            }
            else
            {
                joints[0].Translation = pose[0].Translation + _offset;
            }

            // transform the joint hierarchy
            idHelper.TransformJoints(joints, _jointParents, 1, joints.Length - 1);

            // get the bounds of the default pose
            frameBounds = _model.GetBounds(null);
        }
Beispiel #14
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 #15
0
		public bool AddBounds(int currentTime, ref idBounds bounds, bool removeOriginOffset)
		{
			if((_endTime > 0) && (currentTime > _endTime))
			{
				return false;
			}

			idAnim anim = GetAnimation();

			if(anim == null)
			{
				return false;
			}

			float weight = GetWeight(currentTime);

			if(weight == 0)
			{
				return false;
			}

			int time = GetAnimationTime(currentTime);
			int animCount = anim.AnimationCount;
			bool addOrigin = (_allowMove == false) || (removeOriginOffset == false);

			idBounds b;
			Vector3 pos;

			for(int i = 0; i < animCount; i++)
			{
				if(anim.GetBounds(out b, i, time, _cycle) == true)
				{
					if(addOrigin == true)
					{
						anim.GetOrigin(out pos, i, time, _cycle);
						b.Translate(pos);
					}

					bounds.AddBounds(b);
				}
			}

			return true;
		}
Beispiel #16
0
        public bool AddBounds(int currentTime, ref idBounds bounds, bool removeOriginOffset)
        {
            if ((_endTime > 0) && (currentTime > _endTime))
            {
                return(false);
            }

            idAnim anim = GetAnimation();

            if (anim == null)
            {
                return(false);
            }

            float weight = GetWeight(currentTime);

            if (weight == 0)
            {
                return(false);
            }

            int  time      = GetAnimationTime(currentTime);
            int  animCount = anim.AnimationCount;
            bool addOrigin = (_allowMove == false) || (removeOriginOffset == false);

            idBounds b;
            Vector3  pos;

            for (int i = 0; i < animCount; i++)
            {
                if (anim.GetBounds(out b, i, time, _cycle) == true)
                {
                    if (addOrigin == true)
                    {
                        anim.GetOrigin(out pos, i, time, _cycle);
                        b.Translate(pos);
                    }

                    bounds.AddBounds(b);
                }
            }

            return(true);
        }
Beispiel #17
0
        /// <summary>
        ///
        /// </summary>
        /// <remarks>Must have been linked with an entity and ID before.</remarks>
        /// <param name="clip"></param>
        public void Link(idClip clip)
        {
            if (this.Disposed == true)
            {
                throw new ObjectDisposedException("idClipModel");
            }

            if (_entity == null)
            {
                return;
            }

            if (_clipLinks != null)
            {
                Unlink();                 // unlink from old position.
            }

            if (_bounds.IsCleared == true)
            {
                return;
            }

            // set the abs box
            if (_axis != Matrix.Identity)
            {
                // expand for rotation
                _absBounds = idBounds.FromTransformedBounds(_bounds, _origin, _axis);
            }
            else
            {
                // normal
                _absBounds.Min = _bounds.Min + _origin;
                _absBounds.Max = _bounds.Max + _origin;
            }

            // because movement is clipped an epsilon away from an actual edge,
            // we must fully check even when bounding boxes don't quite touch
            _absBounds.Min -= new Vector3(BoxEpsilon, BoxEpsilon, BoxEpsilon);
            _absBounds.Max += new Vector3(BoxEpsilon, BoxEpsilon, BoxEpsilon);

            // TODO: this may not be correct! from what I can gleam it just starts at the start of the array
            LinkSectors(clip.Sectors[0]);
        }
Beispiel #18
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 #19
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="?"></param>
        /// <returns>False if no part of the bounds extends beyond the near plane.</returns>
        public bool ConstrainToBounds(idBounds bounds)
        {
            float   min, max;
            Vector3 tmp = new Vector3(_axis.M11, _axis.M12, _axis.M12);

            bounds.AxisProjection(tmp, out min, out max);

            float newDFar = max - (tmp * _origin).Length();

            if (newDFar <= _dNear)
            {
                MoveFarDistance(_dNear + 1.0f);
                return(false);
            }

            MoveFarDistance(newDFar);

            return(true);
        }
Beispiel #20
0
        private void SetupBox(idBounds bounds)
        {
            if (_type != TraceModelType.Box)
            {
                InitBox();
            }

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

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

            // set polygon plane distances
            _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[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 #21
0
        public idBounds GetBounds(int time, int cycleCount)
        {
            FrameBlend frame = ConvertTimeToFrame(time, cycleCount);

            idBounds bounds = _bounds[frame.Frame1];

            bounds.AddBounds(_bounds[frame.Frame2]);

            // origin position
            Vector3 offset = _baseFrame[0].Translation;

            if ((_jointInfo[0].AnimationBits & (AnimationBits.TranslationX | AnimationBits.TranslationY | AnimationBits.TranslationZ)) != 0)
            {
                int componentOffset1 = _animatedComponentCount * frame.Frame1 + _jointInfo[0].FirstComponent;
                int componentOffset2 = _animatedComponentCount * frame.Frame2 + _jointInfo[0].FirstComponent;

                if ((_jointInfo[0].AnimationBits & AnimationBits.TranslationX) == AnimationBits.TranslationX)
                {
                    offset.X = _componentFrames[componentOffset1] * frame.FrontLerp + _componentFrames[componentOffset2] * frame.BackLerp;
                    componentOffset1++;
                    componentOffset2++;
                }

                if ((_jointInfo[0].AnimationBits & AnimationBits.TranslationY) == AnimationBits.TranslationY)
                {
                    offset.Y = _componentFrames[componentOffset1] * frame.FrontLerp + _componentFrames[componentOffset2] * frame.BackLerp;
                    componentOffset1++;
                    componentOffset2++;
                }

                if ((_jointInfo[0].AnimationBits & AnimationBits.TranslationZ) == AnimationBits.TranslationZ)
                {
                    offset.Z = _componentFrames[componentOffset1] * frame.FrontLerp + _componentFrames[componentOffset2] * frame.BackLerp;
                }
            }

            bounds.Min -= offset;
            bounds.Max -= offset;

            return(bounds);
        }
        public override void InitEmpty(string name)
        {
            if (this.Disposed == true)
            {
                throw new ObjectDisposedException(this.GetType().Name);
            }

            // model names of the form _area* are static parts of the
            // world, and have already been considered for optimized shadows
            // other model names are inline entity models, and need to be
            // shadowed normally
            _isStaticWorldModel = (name.StartsWith("_area") == true);

            _name       = name;
            _reloadable = false;             // if it didn't come from a file, we can't reload it

            Purge();

            _purged = false;
            _bounds = idBounds.Zero;
        }
Beispiel #23
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;
        }
Beispiel #24
0
		/// <summary>
		/// 
		/// </summary>
		/// <remarks>Must have been linked with an entity and ID before.</remarks>
		/// <param name="clip"></param>
		public void Link(idClip clip)
		{
			if(this.Disposed == true)
			{
				throw new ObjectDisposedException("idClipModel");
			}

			if(_entity == null)
			{
				return;
			}

			if(_clipLinks != null)
			{
				Unlink(); // unlink from old position.
			}

			if(_bounds.IsCleared == true)
			{
				return;
			}
			
			// set the abs box
			if(_axis != Matrix.Identity)
			{
				// expand for rotation
				_absBounds = idBounds.FromTransformedBounds(_bounds, _origin, _axis);
			}
			else
			{
				// normal
				_absBounds.Min = _bounds.Min + _origin;
				_absBounds.Max = _bounds.Max + _origin;
			}

			// because movement is clipped an epsilon away from an actual edge,
			// we must fully check even when bounding boxes don't quite touch
			_absBounds.Min -= new Vector3(BoxEpsilon, BoxEpsilon, BoxEpsilon);
			_absBounds.Max += new Vector3(BoxEpsilon, BoxEpsilon, BoxEpsilon);

			// TODO: this may not be correct! from what I can gleam it just starts at the start of the array
			LinkSectors(clip.Sectors[0]);
		}
/*
===============================================================================

Writing of collision model file

===============================================================================
*/

void CM_GetNodeBounds( idBounds *bounds, cm_node_t *node );
Beispiel #26
0
		public void LoadModel(idTraceModel traceModel)
		{
			if(this.Disposed == true)
			{
				throw new ObjectDisposedException("idClipModel");
			}

			_collisionModelHandle = 0;
			_renderModelHandle = -1;			
			_traceModelCache = GetTraceModelCache(traceModel);

			_bounds = traceModel.Bounds;
		}
        /// <summary>
        ///
        /// </summary>
        /// <remarks>
        /// The mergeShadows option allows surfaces with different textures to share
        /// silhouette edges for shadow calculation, instead of leaving shared edges
        /// hanging.
        /// <para/>
        /// If any of the original shaders have the noSelfShadow flag set, the surfaces
        /// can't be merged, because they will need to be drawn in different order.
        /// <para/>
        /// If there is only one surface, a separate merged surface won't be generated.
        /// <para/>
        /// A model with multiple surfaces can't later have a skinned shader change the
        /// state of the noSelfShadow flag.
        /// <para/>
        /// -----------------
        /// <para/>
        /// Creates mirrored copies of two sided surfaces with normal maps, which would
        /// otherwise light funny.
        /// <para/>
        /// Extends the bounds of deformed surfaces so they don't cull incorrectly at screen edges.
        /// </remarks>
        public override void FinishSurfaces()
        {
            if (this.Disposed == true)
            {
                throw new ObjectDisposedException(this.GetType().Name);
            }

            _purged = false;

            // make sure we don't have a huge bounds even if we don't finish everything
            _bounds = idBounds.Zero;

            if (_surfaces.Count == 0)
            {
                return;
            }

            // renderBump doesn't care about most of this
            if (_fastLoad == true)
            {
                _bounds = idBounds.Zero;

                foreach (RenderModelSurface surf in _surfaces)
                {
                    idHelper.BoundTriangleSurface(surf.Geometry);
                    _bounds.AddBounds(surf.Geometry.Bounds);
                }

                return;
            }

            // cleanup all the final surfaces, but don't create sil edges
            int totalVerts   = 0;
            int totalIndexes = 0;

            // decide if we are going to merge all the surfaces into one shadower
            int numOriginalSurfaces = _surfaces.Count;

            // make sure there aren't any NULL shaders or geometry
            for (int i = 0; i < numOriginalSurfaces; i++)
            {
                RenderModelSurface surf = _surfaces[i];

                if ((surf.Geometry == null) || (surf.Material == null))
                {
                    MakeDefault();
                    idConsole.Error("Model {0}, surface {1} had NULL goemetry", this.Name, i);
                }

                if (surf.Material == null)
                {
                    MakeDefault();
                    idConsole.Error("Model {0}, surface {1} had NULL material", this.Name, i);
                }
            }

            // duplicate and reverse triangles for two sided bump mapped surfaces
            // note that this won't catch surfaces that have their shaders dynamically
            // changed, and won't work with animated models.
            // It is better to create completely separate surfaces, rather than
            // add vertexes and indexes to the existing surface, because the
            // tangent generation wouldn't like the acute shared edges
            for (int i = 0; i < numOriginalSurfaces; i++)
            {
                RenderModelSurface surf = _surfaces[i];

                if (surf.Material.ShouldCreateBackSides == true)
                {
                    idConsole.Warning("TODO: should create back sides");

                    /*srfTriangles_t *newTri;
                     *
                     * newTri = R_CopyStaticTriSurf( surf->geometry );
                     * R_ReverseTriangles( newTri );
                     *
                     * modelSurface_t	newSurf;
                     *
                     * newSurf.shader = surf->shader;
                     * newSurf.geometry = newTri;
                     *
                     * AddSurface( newSurf );*/
                }
            }

            // clean the surfaces
            // TODO: clean surfaces

            /*for ( i = 0 ; i < surfaces.Num() ; i++ ) {
             *      const modelSurface_t	*surf = &surfaces[i];
             *
             *      R_CleanupTriangles( surf->geometry, surf->geometry->generateNormals, true, surf->shader->UseUnsmoothedTangents() );
             *      if ( surf->shader->SurfaceCastsShadow() ) {
             *              totalVerts += surf->geometry->numVerts;
             *              totalIndexes += surf->geometry->numIndexes;
             *      }
             * }*/

            // add up the total surface area for development information
            // TODO: surf dev info

            /*for ( i = 0 ; i < surfaces.Num() ; i++ ) {
             *      const modelSurface_t	*surf = &surfaces[i];
             *      srfTriangles_t	*tri = surf->geometry;
             *
             *      for ( int j = 0 ; j < tri->numIndexes ; j += 3 ) {
             *              float	area = idWinding::TriangleArea( tri->verts[tri->indexes[j]].xyz,
             *                       tri->verts[tri->indexes[j+1]].xyz,  tri->verts[tri->indexes[j+2]].xyz );
             *              const_cast<idMaterial *>(surf->shader)->AddToSurfaceArea( area );
             *      }
             * }*/

            // calculate the bounds
            int surfaceCount = _surfaces.Count;

            if (surfaceCount == 0)
            {
                _bounds = idBounds.Zero;
            }
            else
            {
                _bounds.Clear();

                for (int i = 0; i < surfaceCount; i++)
                {
                    RenderModelSurface surf = _surfaces[i];

                    // if the surface has a deformation, increase the bounds
                    // the amount here is somewhat arbitrary, designed to handle
                    // autosprites and flares, but could be done better with exact
                    // deformation information.
                    // Note that this doesn't handle deformations that are skinned in
                    // at run time...
                    if (surf.Material.Deform != DeformType.None)
                    {
                        idConsole.Warning("TODO: deform");

                        /*srfTriangles_t	*tri = surf->geometry;
                         * idVec3	mid = ( tri->bounds[1] + tri->bounds[0] ) * 0.5f;
                         * float	radius = ( tri->bounds[0] - mid ).Length();
                         * radius += 20.0f;
                         *
                         * tri->bounds[0][0] = mid[0] - radius;
                         * tri->bounds[0][1] = mid[1] - radius;
                         * tri->bounds[0][2] = mid[2] - radius;
                         *
                         * tri->bounds[1][0] = mid[0] + radius;
                         * tri->bounds[1][1] = mid[1] + radius;
                         * tri->bounds[1][2] = mid[2] + radius;*/
                    }

                    // add to the model bounds
                    _bounds.AddBounds(surf.Geometry.Bounds);
                }
            }
        }
Beispiel #28
0
        public bool GetBounds(int currentTime, out idBounds bounds)
        {
            bounds = idBounds.Zero;

            if ((_modelDef == null) || (_modelDef.Model == null))
            {
                return(false);
            }

            int count = 0;

            if (_afPoseJoints.Count > 0)
            {
                bounds = _afPoseBounds;
                count  = 1;
            }

            for (int i = (int)AnimationChannel.All; i < (int)AnimationChannel.Count; i++)
            {
                for (int j = 0; j < idR.AnimationCountPerChannel; j++)
                {
                    idAnimBlend blend = _channels[i, j];

                    if (blend.AddBounds(currentTime, ref bounds, _removeOriginOffset) == true)
                    {
                        count++;
                    }
                }
            }

            if (count == 0)
            {
                if (_frameBounds.IsCleared == false)
                {
                    bounds = _frameBounds;
                    return(true);
                }
                else
                {
                    return(false);
                }
            }

            bounds.Translate(_modelDef.VisualOffset);

            if (idR.CvarSystem.GetBool("g_debugBounds") == true)
            {
                idConsole.Warning("TODO: g_debugBounds");

                /*if ( bounds[1][0] - bounds[0][0] > 2048 || bounds[1][1] - bounds[0][1] > 2048 ) {
                 *      if ( entity ) {
                 *              gameLocal.Warning( "big frameBounds on entity '%s' with model '%s': %f,%f", entity->name.c_str(), modelDef->ModelHandle()->Name(), bounds[1][0] - bounds[0][0], bounds[1][1] - bounds[0][1] );
                 *      } else {
                 *              gameLocal.Warning( "big frameBounds on model '%s': %f,%f", modelDef->ModelHandle()->Name(), bounds[1][0] - bounds[0][0], bounds[1][1] - bounds[0][1] );
                 *      }
                 * }*/
            }

            _frameBounds = bounds;

            return(true);
        }
Beispiel #29
0
		public override bool Parse(string text)
		{
			if(this.Disposed == true)
			{
				throw new ObjectDisposedException(this.GetType().Name);
			}

			idToken token;
			string tokenLower;

			idLexer lexer = new idLexer(idDeclFile.LexerOptions);
			lexer.LoadMemory(text, this.FileName, this.LineNumber);
			lexer.SkipUntilString("{");

			List<idParticleStage> stages = new List<idParticleStage>();

			_depthHack = 0.0f;

			while(true)
			{
				if((token = lexer.ReadToken()) == null)
				{
					break;
				}

				tokenLower = token.ToString().ToLower();

				if(tokenLower == "}")
				{
					break;
				}
				else if(tokenLower == "{")
				{
					idParticleStage stage = ParseParticleStage(lexer);

					if(stage == null)
					{
						lexer.Warning("Particle stage parse failed");
						MakeDefault();

						return false;
					}

					stages.Add(stage);
				}
				else if(tokenLower == "depthhack")
				{
					_depthHack = lexer.ParseFloat();
				}
				else
				{
					lexer.Warning("bad token {0}", token.ToString());
					MakeDefault();

					return false;
				}
			}

			_stages = stages.ToArray();

			//
			// calculate the bounds
			//
			_bounds.Clear();

			int count = _stages.Length;

			for(int i = 0; i < count; i++)
			{
				idConsole.Warning("TODO: GetStageBounds");
				// TODO: GetStageBounds(stages[i]);
				_bounds += _stages[i].Bounds;
			}

			if(_bounds.Volume <= 0.1f)
			{
				_bounds = idBounds.Expand(idBounds.Zero, 8.0f);
			}

			return true;
		}
Beispiel #30
0
		private void SetupBox(idBounds bounds)
		{
			if(_type != TraceModelType.Box)
			{
				InitBox();
			}

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

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

			// set polygon plane distances
			_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[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;
		}
		public override void AddSurface(RenderModelSurface surface)
		{
			if(this.Disposed == true)
			{
				throw new ObjectDisposedException(this.GetType().Name);
			}

			_surfaces.Add(surface);

			if(surface.Geometry != null)
			{
				_bounds += surface.Geometry.Bounds;
			}
		}
Beispiel #32
0
		public bool GetBounds(int currentTime, out idBounds bounds)
		{
			bounds = idBounds.Zero;

			if((_modelDef == null) || (_modelDef.Model == null))
			{
				return false;
			}

			int count = 0;

			if(_afPoseJoints.Count > 0)
			{
				bounds = _afPoseBounds;
				count = 1;
			}

			for(int i = (int) AnimationChannel.All; i < (int) AnimationChannel.Count; i++)
			{
				for(int j = 0; j < idR.AnimationCountPerChannel; j++)
				{
					idAnimBlend blend = _channels[i, j];
				
					if(blend.AddBounds(currentTime, ref bounds, _removeOriginOffset) == true)
					{
						count++;
					}
				}
			}

			if(count == 0)
			{
				if(_frameBounds.IsCleared == false)
				{
					bounds = _frameBounds;
					return true;
				}
				else
				{
					return false;
				}
			}

			bounds.Translate(_modelDef.VisualOffset);

			if(idR.CvarSystem.GetBool("g_debugBounds") == true)
			{
				idConsole.Warning("TODO: g_debugBounds");

				/*if ( bounds[1][0] - bounds[0][0] > 2048 || bounds[1][1] - bounds[0][1] > 2048 ) {
					if ( entity ) {
						gameLocal.Warning( "big frameBounds on entity '%s' with model '%s': %f,%f", entity->name.c_str(), modelDef->ModelHandle()->Name(), bounds[1][0] - bounds[0][0], bounds[1][1] - bounds[0][1] );
					} else {
						gameLocal.Warning( "big frameBounds on model '%s': %f,%f", modelDef->ModelHandle()->Name(), bounds[1][0] - bounds[0][0], bounds[1][1] - bounds[0][1] );
					}
				}*/
			}

			_frameBounds = bounds;

			return true;
		}
Beispiel #33
0
		private void Dispose(bool disposing)
		{
			if(this.Disposed == true)
			{
				throw new ObjectDisposedException(this.GetType().Name);
			}

			if(disposing == true)
			{
				this.Bounds = idBounds.Zero;
				this.Indexes = null;
				this.Vertices = null;
				this.ShadowVertices = null;
				this.IndexCache = null;
				this.AmbientCache = null;
			}

			_disposed = true;
		}
Beispiel #34
0
		public bool LoadAnimation(string fileName)
		{
			idToken token;
			idLexer lexer = new idLexer(LexerOptions.AllowPathNames | LexerOptions.NoStringEscapeCharacters | LexerOptions.NoStringConcatination);

			if(lexer.LoadFile(fileName) == false)
			{
				return false;
			}

			Clear();

			_name = fileName;

			lexer.ExpectTokenString(idRenderModel_MD5.VersionString);
			int version = lexer.ParseInt();

			if(version != idRenderModel_MD5.Version)
			{
				lexer.Error("Invalid version {0}.  Should be version {1}", version, idRenderModel_MD5.Version);
			}

			// skip the commandline
			lexer.ExpectTokenString("commandline");
			lexer.ReadToken();

			// parse num frames
			lexer.ExpectTokenString("numFrames");
			int frameCount = lexer.ParseInt();

			if(frameCount <= 0)
			{
				lexer.Error("Invalid number of frames: {0}", frameCount);
			}

			// parse num joints
			lexer.ExpectTokenString("numJoints");
			int jointCount = lexer.ParseInt();

			if(jointCount <= 0)
			{
				lexer.Error("Invalid number of joints: {0}", jointCount);
			}

			// parse frame rate
			lexer.ExpectTokenString("frameRate");
			_frameRate = lexer.ParseInt();

			if(_frameRate < 0)
			{
				lexer.Error("Invalid frame rate: {0}", _frameRate);
			}

			// parse number of animated components
			lexer.ExpectTokenString("numAnimatedComponents");
			_animatedComponentCount = lexer.ParseInt();

			if((_animatedComponentCount < 0) || (_animatedComponentCount > (jointCount * 6)))
			{
				lexer.Error("Invalid number of animated components: {0}", _animatedComponentCount);
			}

			// parse the hierarchy
			_jointInfo = new JointAnimationInfo[jointCount];

			lexer.ExpectTokenString("hierarchy");
			lexer.ExpectTokenString("{");

			for(int i = 0; i < jointCount; i++)
			{
				token = lexer.ReadToken();

				_jointInfo[i] = new JointAnimationInfo();
				_jointInfo[i].NameIndex = idR.AnimManager.GetJointIndex(token.ToString());

				// parse parent num				
				_jointInfo[i].ParentIndex = lexer.ParseInt();

				if(_jointInfo[i].ParentIndex >= i)
				{
					lexer.Error("Invalid parent num: {0}", _jointInfo[i].ParentIndex);
				}

				if((i != 0) && (_jointInfo[i].ParentIndex < 0))
				{
					lexer.Error("Animations may have only one root joint");
				}

				// parse anim bits
				_jointInfo[i].AnimationBits = (AnimationBits) lexer.ParseInt();

				if(((int) _jointInfo[i].AnimationBits & ~63) != 0)
				{
					lexer.Error("Invalid anim bits: {0}", _jointInfo[i].AnimationBits);
				}

				// parse first component
				_jointInfo[i].FirstComponent = lexer.ParseInt();

				if((_animatedComponentCount > 0) && ((_jointInfo[i].FirstComponent < 0) || (_jointInfo[i].FirstComponent >= _animatedComponentCount)))
				{
					lexer.Error("Invalid first component: {0}", _jointInfo[i].FirstComponent);
				}
			}

			lexer.ExpectTokenString("}");

			// parse bounds
			lexer.ExpectTokenString("bounds");
			lexer.ExpectTokenString("{");

			_bounds = new idBounds[frameCount];

			for(int i = 0; i < frameCount; i++)
			{
				float[] tmp = lexer.Parse1DMatrix(3);
				float[] tmp2 = lexer.Parse1DMatrix(3);

				_bounds[i] = new idBounds(
					new Vector3(tmp[0], tmp[1], tmp[2]),
					new Vector3(tmp2[0], tmp2[1], tmp2[2])
				);
			}

			lexer.ExpectTokenString("}");

			// parse base frame
			_baseFrame = new idJointQuaternion[jointCount];

			lexer.ExpectTokenString("baseframe");
			lexer.ExpectTokenString("{");

			for(int i = 0; i < jointCount; i++)
			{
				float[] tmp = lexer.Parse1DMatrix(3);
				float[] tmp2 = lexer.Parse1DMatrix(3);

				idCompressedQuaternion q = new idCompressedQuaternion(tmp2[0], tmp2[1], tmp2[2]);
				

				_baseFrame[i] = new idJointQuaternion();
				_baseFrame[i].Translation = new Vector3(tmp[0], tmp[1], tmp[2]);
				_baseFrame[i].Quaternion = q.ToQuaternion();
			}

			lexer.ExpectTokenString("}");

			// parse frames
			_componentFrames = new float[_animatedComponentCount * frameCount];
			int frameOffset = 0;

			for(int i = 0; i < frameCount; i++)
			{
				lexer.ExpectTokenString("frame");
				int count = lexer.ParseInt();

				if(count != i)
				{
					lexer.Error("Expected frame number {0}", i);
				}

				lexer.ExpectTokenString("{");

				for(int j = 0; j < _animatedComponentCount; j++, frameOffset++)
				{
					_componentFrames[frameOffset] = lexer.ParseFloat();
				}

				lexer.ExpectTokenString("}");
			}

			// get total move delta
			if(_animatedComponentCount == 0)
			{
				_totalDelta = Vector3.Zero;
			}
			else
			{
				int componentOffset = _jointInfo[0].FirstComponent;

				if((_jointInfo[0].AnimationBits & AnimationBits.TranslationX) == AnimationBits.TranslationX)
				{
					for(int i = 0; i < frameCount; i++)
					{
						_componentFrames[componentOffset + (_animatedComponentCount * i)] -= _baseFrame[0].Translation.X;
					}

					_totalDelta.X = _componentFrames[componentOffset + (_animatedComponentCount * (frameCount - 1))];
					componentOffset++;
				}
				else
				{
					_totalDelta.X = 0;
				}

				if((_jointInfo[0].AnimationBits & AnimationBits.TranslationY) == AnimationBits.TranslationY)
				{
					for(int i = 0; i < frameCount; i++)
					{
						_componentFrames[componentOffset + (_animatedComponentCount * i)] -= _baseFrame[0].Translation.Y;
					}

					_totalDelta.Y = _componentFrames[componentOffset + (_animatedComponentCount * (frameCount - 1))];
					componentOffset++;
				}
				else
				{
					_totalDelta.Y = 0;
				}

				if((_jointInfo[0].AnimationBits & AnimationBits.TranslationZ) == AnimationBits.TranslationZ)
				{
					for(int i = 0; i < frameCount; i++)
					{
						_componentFrames[componentOffset + (_animatedComponentCount * i)] -= _baseFrame[0].Translation.Z;
					}

					_totalDelta.Z = _componentFrames[componentOffset + (_animatedComponentCount * (frameCount - 1))];
				}
				else
				{
					_totalDelta.Z = 0;
				}
			}

			_baseFrame[0].Translation = Vector3.Zero;

			// we don't count last frame because it would cause a 1 frame pause at the end
			_animLength = ((frameCount - 1) * 1000 + _frameRate - 1) / _frameRate;

			// done
			return true;
		}
Beispiel #35
0
 public idTraceModel(idBounds bounds, int sideCount)
 {
     SetupCylinder(bounds, sideCount);
 }
Beispiel #36
0
        private void InitDefaultPhysics(Vector3 origin, Matrix axis)
        {
            string      temp      = _spawnArgs.GetString("clipmodel", "");
            idClipModel clipModel = null;

            // check if a clipmodel key/value pair is set
            if (temp != string.Empty)
            {
                if (idClipModel.CheckModel(temp) != null)
                {
                    clipModel = new idClipModel(temp);
                }
            }

            if (_spawnArgs.GetBool("noclipmodel", false) == false)
            {
                // check if mins/maxs or size key/value pairs are set
                if (clipModel == null)
                {
                    idBounds bounds       = idBounds.Zero;
                    bool     setClipModel = false;

                    if ((_spawnArgs.ContainsKey("mins") == true) &&
                        (_spawnArgs.ContainsKey("maxs") == true))
                    {
                        bounds       = new idBounds(_spawnArgs.GetVector3("mins"), _spawnArgs.GetVector3("maxs"));
                        setClipModel = true;

                        if ((bounds.Min.X > bounds.Max.X) ||
                            (bounds.Min.Y > bounds.Max.Y) ||
                            (bounds.Min.Z > bounds.Max.Z))
                        {
                            idConsole.Error("Invalid bounds '{0}'-'{1}' on entity '{2}'", bounds.Min, bounds.Max, this.Name);
                        }
                    }
                    else if (_spawnArgs.ContainsKey("size") == true)
                    {
                        Vector3 size = _spawnArgs.GetVector3("size");

                        if ((size.X < 0.0f) ||
                            (size.Y < 0.0f) ||
                            (size.Z < 0.0f))
                        {
                            idConsole.Error("Invalid size '{0}' on entity '{1}'", size, this.Name);
                        }

                        setClipModel = true;
                        bounds       = new idBounds(
                            new Vector3(size.X * -0.5f, size.Y * -0.5f, 0.0f),
                            new Vector3(size.X * 0.5f, size.Y * 0.5f, size.Z)
                            );
                    }

                    if (setClipModel == true)
                    {
                        int sideCount = _spawnArgs.GetInteger("cyclinder", 0);

                        idTraceModel traceModel = new idTraceModel();

                        if (sideCount > 0)
                        {
                            idConsole.Warning("TODO: traceModel.SetupCyclinder(bounds, (sideCount < 3) ? 3 : sideCount);");
                        }
                        else if ((sideCount = _spawnArgs.GetInteger("cone", 0)) > 0)
                        {
                            idConsole.Warning("TODO: traceModel.SetupCone(bounds, (sideCount < 3) ? 3 : sideCount);");
                        }
                        else
                        {
                            traceModel.SetupBox(bounds);
                        }

                        clipModel = new idClipModel(traceModel);
                    }
                }

                // check if the visual model can be used as collision model
                if (clipModel == null)
                {
                    temp = _spawnArgs.GetString("model");

                    if (temp != string.Empty)
                    {
                        if (idClipModel.CheckModel(temp) != null)
                        {
                            clipModel = new idClipModel(temp);
                        }
                    }
                }
            }

            _defaultPhysicsObject.Self = this;
            _defaultPhysicsObject.SetClipModel(clipModel, 1.0f);
            _defaultPhysicsObject.SetOrigin(origin);
            _defaultPhysicsObject.SetAxis(axis);

            _physics = _defaultPhysicsObject;
        }
Beispiel #37
0
 /// <summary>
 /// Axial bounding box.
 /// </summary>
 /// <param name="boxBounds"></param>
 public idTraceModel(idBounds boxBounds)
 {
     InitBox();
     SetupBox(boxBounds);
 }
Beispiel #38
0
        public bool LoadAnimation(string fileName)
        {
            idToken token;
            idLexer lexer = new idLexer(LexerOptions.AllowPathNames | LexerOptions.NoStringEscapeCharacters | LexerOptions.NoStringConcatination);

            if (lexer.LoadFile(fileName) == false)
            {
                return(false);
            }

            Clear();

            _name = fileName;

            lexer.ExpectTokenString(idRenderModel_MD5.VersionString);
            int version = lexer.ParseInt();

            if (version != idRenderModel_MD5.Version)
            {
                lexer.Error("Invalid version {0}.  Should be version {1}", version, idRenderModel_MD5.Version);
            }

            // skip the commandline
            lexer.ExpectTokenString("commandline");
            lexer.ReadToken();

            // parse num frames
            lexer.ExpectTokenString("numFrames");
            int frameCount = lexer.ParseInt();

            if (frameCount <= 0)
            {
                lexer.Error("Invalid number of frames: {0}", frameCount);
            }

            // parse num joints
            lexer.ExpectTokenString("numJoints");
            int jointCount = lexer.ParseInt();

            if (jointCount <= 0)
            {
                lexer.Error("Invalid number of joints: {0}", jointCount);
            }

            // parse frame rate
            lexer.ExpectTokenString("frameRate");
            _frameRate = lexer.ParseInt();

            if (_frameRate < 0)
            {
                lexer.Error("Invalid frame rate: {0}", _frameRate);
            }

            // parse number of animated components
            lexer.ExpectTokenString("numAnimatedComponents");
            _animatedComponentCount = lexer.ParseInt();

            if ((_animatedComponentCount < 0) || (_animatedComponentCount > (jointCount * 6)))
            {
                lexer.Error("Invalid number of animated components: {0}", _animatedComponentCount);
            }

            // parse the hierarchy
            _jointInfo = new JointAnimationInfo[jointCount];

            lexer.ExpectTokenString("hierarchy");
            lexer.ExpectTokenString("{");

            for (int i = 0; i < jointCount; i++)
            {
                token = lexer.ReadToken();

                _jointInfo[i]           = new JointAnimationInfo();
                _jointInfo[i].NameIndex = idR.AnimManager.GetJointIndex(token.ToString());

                // parse parent num
                _jointInfo[i].ParentIndex = lexer.ParseInt();

                if (_jointInfo[i].ParentIndex >= i)
                {
                    lexer.Error("Invalid parent num: {0}", _jointInfo[i].ParentIndex);
                }

                if ((i != 0) && (_jointInfo[i].ParentIndex < 0))
                {
                    lexer.Error("Animations may have only one root joint");
                }

                // parse anim bits
                _jointInfo[i].AnimationBits = (AnimationBits)lexer.ParseInt();

                if (((int)_jointInfo[i].AnimationBits & ~63) != 0)
                {
                    lexer.Error("Invalid anim bits: {0}", _jointInfo[i].AnimationBits);
                }

                // parse first component
                _jointInfo[i].FirstComponent = lexer.ParseInt();

                if ((_animatedComponentCount > 0) && ((_jointInfo[i].FirstComponent < 0) || (_jointInfo[i].FirstComponent >= _animatedComponentCount)))
                {
                    lexer.Error("Invalid first component: {0}", _jointInfo[i].FirstComponent);
                }
            }

            lexer.ExpectTokenString("}");

            // parse bounds
            lexer.ExpectTokenString("bounds");
            lexer.ExpectTokenString("{");

            _bounds = new idBounds[frameCount];

            for (int i = 0; i < frameCount; i++)
            {
                float[] tmp  = lexer.Parse1DMatrix(3);
                float[] tmp2 = lexer.Parse1DMatrix(3);

                _bounds[i] = new idBounds(
                    new Vector3(tmp[0], tmp[1], tmp[2]),
                    new Vector3(tmp2[0], tmp2[1], tmp2[2])
                    );
            }

            lexer.ExpectTokenString("}");

            // parse base frame
            _baseFrame = new idJointQuaternion[jointCount];

            lexer.ExpectTokenString("baseframe");
            lexer.ExpectTokenString("{");

            for (int i = 0; i < jointCount; i++)
            {
                float[] tmp  = lexer.Parse1DMatrix(3);
                float[] tmp2 = lexer.Parse1DMatrix(3);

                idCompressedQuaternion q = new idCompressedQuaternion(tmp2[0], tmp2[1], tmp2[2]);


                _baseFrame[i]             = new idJointQuaternion();
                _baseFrame[i].Translation = new Vector3(tmp[0], tmp[1], tmp[2]);
                _baseFrame[i].Quaternion  = q.ToQuaternion();
            }

            lexer.ExpectTokenString("}");

            // parse frames
            _componentFrames = new float[_animatedComponentCount * frameCount];
            int frameOffset = 0;

            for (int i = 0; i < frameCount; i++)
            {
                lexer.ExpectTokenString("frame");
                int count = lexer.ParseInt();

                if (count != i)
                {
                    lexer.Error("Expected frame number {0}", i);
                }

                lexer.ExpectTokenString("{");

                for (int j = 0; j < _animatedComponentCount; j++, frameOffset++)
                {
                    _componentFrames[frameOffset] = lexer.ParseFloat();
                }

                lexer.ExpectTokenString("}");
            }

            // get total move delta
            if (_animatedComponentCount == 0)
            {
                _totalDelta = Vector3.Zero;
            }
            else
            {
                int componentOffset = _jointInfo[0].FirstComponent;

                if ((_jointInfo[0].AnimationBits & AnimationBits.TranslationX) == AnimationBits.TranslationX)
                {
                    for (int i = 0; i < frameCount; i++)
                    {
                        _componentFrames[componentOffset + (_animatedComponentCount * i)] -= _baseFrame[0].Translation.X;
                    }

                    _totalDelta.X = _componentFrames[componentOffset + (_animatedComponentCount * (frameCount - 1))];
                    componentOffset++;
                }
                else
                {
                    _totalDelta.X = 0;
                }

                if ((_jointInfo[0].AnimationBits & AnimationBits.TranslationY) == AnimationBits.TranslationY)
                {
                    for (int i = 0; i < frameCount; i++)
                    {
                        _componentFrames[componentOffset + (_animatedComponentCount * i)] -= _baseFrame[0].Translation.Y;
                    }

                    _totalDelta.Y = _componentFrames[componentOffset + (_animatedComponentCount * (frameCount - 1))];
                    componentOffset++;
                }
                else
                {
                    _totalDelta.Y = 0;
                }

                if ((_jointInfo[0].AnimationBits & AnimationBits.TranslationZ) == AnimationBits.TranslationZ)
                {
                    for (int i = 0; i < frameCount; i++)
                    {
                        _componentFrames[componentOffset + (_animatedComponentCount * i)] -= _baseFrame[0].Translation.Z;
                    }

                    _totalDelta.Z = _componentFrames[componentOffset + (_animatedComponentCount * (frameCount - 1))];
                }
                else
                {
                    _totalDelta.Z = 0;
                }
            }

            _baseFrame[0].Translation = Vector3.Zero;

            // we don't count last frame because it would cause a 1 frame pause at the end
            _animLength = ((frameCount - 1) * 1000 + _frameRate - 1) / _frameRate;

            // done
            return(true);
        }
Beispiel #39
0
		/// <summary>
		/// 
		/// </summary>
		/// <param name="?"></param>
		/// <returns>False if no part of the bounds extends beyond the near plane.</returns>
		public bool ConstrainToBounds(idBounds bounds)
		{
			float min, max;
			Vector3 tmp = new Vector3(_axis.M11, _axis.M12, _axis.M12);

			bounds.AxisProjection(tmp, out min, out max);

			float newDFar =  max - (tmp * _origin).Length();

			if(newDFar <= _dNear)
			{
				MoveFarDistance(_dNear + 1.0f);
				return false;
			}

			MoveFarDistance(newDFar);

			return true;
		}
Beispiel #40
0
		public idRenderEntity()
		{
			_parameters = new RenderEntityComponent();
			_modelMatrix = Matrix.Identity;
			_referenceBounds = idBounds.Zero;
		}
Beispiel #41
0
		public virtual void SetClipBox(idBounds bounds, float density)
		{
			if(this.Disposed == true)
			{
				throw new ObjectDisposedException(this.GetType().Name);
			}

			SetClipModel(new idClipModel(new idTraceModel(bounds)), density);
		}
Beispiel #42
0
		public void SetupJoints(idJointMatrix[] joints, ref idBounds frameBounds, bool removeOriginOffset)
		{
			if(this.Disposed == true)
			{
				throw new ObjectDisposedException(this.GetType().Name);
			}

			if((_model == null) || (_model.IsDefault == true))
			{
				joints = null;
				frameBounds.Clear();
			}

			// get the number of joints
			int count = _model.JointCount;

			if(count == 0)
			{
				idConsole.Error("model '{0}' has no joints", _model.Name);
			}
			
			// set up initial pose for model (with no pose, model is just a jumbled mess)
			joints = new idJointMatrix[count];
			idJointQuaternion[] pose = this.DefaultPose;
			
			// convert the joint quaternions to joint matrices
			idHelper.ConvertJointQuaternionsToJointMatrices(joints, pose);

			// check if we offset the model by the origin joint
			if(removeOriginOffset == true)
			{
#if VELOCITY_MOVE
				joints[0].Translation(new Vector3(_offset.X, _offset.Y + pose[0].Translation.Y, _offset.Z + pose[0].Translation.Z));
#else
				joints[0].Translation = _offset;
#endif
			} 
			else 
			{
				joints[0].Translation = pose[0].Translation + _offset;
			}

			// transform the joint hierarchy
			idHelper.TransformJoints(joints, _jointParents, 1, joints.Length - 1);
			
			// get the bounds of the default pose
			frameBounds = _model.GetBounds(null);
		}
		/// <summary>
		/// 
		/// </summary>
		/// <remarks>
		/// The mergeShadows option allows surfaces with different textures to share
		/// silhouette edges for shadow calculation, instead of leaving shared edges
		/// hanging.
		/// <para/>
		/// If any of the original shaders have the noSelfShadow flag set, the surfaces
		/// can't be merged, because they will need to be drawn in different order.
		/// <para/>
		/// If there is only one surface, a separate merged surface won't be generated.
		/// <para/>
		/// A model with multiple surfaces can't later have a skinned shader change the
		/// state of the noSelfShadow flag.
		/// <para/>
		/// -----------------
		/// <para/>
		/// Creates mirrored copies of two sided surfaces with normal maps, which would
		/// otherwise light funny.
		/// <para/>
		/// Extends the bounds of deformed surfaces so they don't cull incorrectly at screen edges.
		/// </remarks>
		public override void FinishSurfaces()
		{
			if(this.Disposed == true)
			{
				throw new ObjectDisposedException(this.GetType().Name);
			}

			_purged = false;

			// make sure we don't have a huge bounds even if we don't finish everything
			_bounds = idBounds.Zero;

			if(_surfaces.Count == 0)
			{
				return;
			}
			
			// renderBump doesn't care about most of this
			if(_fastLoad == true)
			{
				_bounds = idBounds.Zero;

				foreach(RenderModelSurface surf in _surfaces)
				{
					idHelper.BoundTriangleSurface(surf.Geometry);
					_bounds.AddBounds(surf.Geometry.Bounds);
				}

				return;
			}

			// cleanup all the final surfaces, but don't create sil edges
			int totalVerts = 0;
			int totalIndexes = 0;

			// decide if we are going to merge all the surfaces into one shadower
			int	numOriginalSurfaces = _surfaces.Count;

			// make sure there aren't any NULL shaders or geometry
			for(int i = 0; i < numOriginalSurfaces; i++)
			{
				RenderModelSurface surf = _surfaces[i];

				if((surf.Geometry == null) || (surf.Material == null))
				{
					MakeDefault();
					idConsole.Error("Model {0}, surface {1} had NULL goemetry", this.Name, i);
				}

				if(surf.Material == null)
				{
					MakeDefault();
					idConsole.Error("Model {0}, surface {1} had NULL material", this.Name, i);
				}
			}

			// duplicate and reverse triangles for two sided bump mapped surfaces
			// note that this won't catch surfaces that have their shaders dynamically
			// changed, and won't work with animated models.
			// It is better to create completely separate surfaces, rather than
			// add vertexes and indexes to the existing surface, because the
			// tangent generation wouldn't like the acute shared edges
			for(int i = 0; i < numOriginalSurfaces; i++)
			{
				RenderModelSurface surf = _surfaces[i];
				
				if(surf.Material.ShouldCreateBackSides == true)
				{
					idConsole.Warning("TODO: should create back sides");

					/*srfTriangles_t *newTri;

					newTri = R_CopyStaticTriSurf( surf->geometry );
					R_ReverseTriangles( newTri );

					modelSurface_t	newSurf;

					newSurf.shader = surf->shader;
					newSurf.geometry = newTri;

					AddSurface( newSurf );*/
				}
			}

			// clean the surfaces
			// TODO: clean surfaces	
			/*for ( i = 0 ; i < surfaces.Num() ; i++ ) {
				const modelSurface_t	*surf = &surfaces[i];

				R_CleanupTriangles( surf->geometry, surf->geometry->generateNormals, true, surf->shader->UseUnsmoothedTangents() );
				if ( surf->shader->SurfaceCastsShadow() ) {
					totalVerts += surf->geometry->numVerts;
					totalIndexes += surf->geometry->numIndexes;
				}
			}*/

			// add up the total surface area for development information
			// TODO: surf dev info
			/*for ( i = 0 ; i < surfaces.Num() ; i++ ) {
				const modelSurface_t	*surf = &surfaces[i];
				srfTriangles_t	*tri = surf->geometry;

				for ( int j = 0 ; j < tri->numIndexes ; j += 3 ) {
					float	area = idWinding::TriangleArea( tri->verts[tri->indexes[j]].xyz,
						 tri->verts[tri->indexes[j+1]].xyz,  tri->verts[tri->indexes[j+2]].xyz );
					const_cast<idMaterial *>(surf->shader)->AddToSurfaceArea( area );
				}
			}*/

			// calculate the bounds
			int surfaceCount = _surfaces.Count;

			if(surfaceCount == 0)
			{
				_bounds = idBounds.Zero;
			}
			else
			{
				_bounds.Clear();

				for(int i = 0; i < surfaceCount; i++)
				{
					RenderModelSurface surf = _surfaces[i];

					// if the surface has a deformation, increase the bounds
					// the amount here is somewhat arbitrary, designed to handle
					// autosprites and flares, but could be done better with exact
					// deformation information.
					// Note that this doesn't handle deformations that are skinned in
					// at run time...
					if(surf.Material.Deform != DeformType.None)
					{
						idConsole.Warning("TODO: deform");

						/*srfTriangles_t	*tri = surf->geometry;
						idVec3	mid = ( tri->bounds[1] + tri->bounds[0] ) * 0.5f;
						float	radius = ( tri->bounds[0] - mid ).Length();
						radius += 20.0f;

						tri->bounds[0][0] = mid[0] - radius;
						tri->bounds[0][1] = mid[1] - radius;
						tri->bounds[0][2] = mid[2] - radius;

						tri->bounds[1][0] = mid[0] + radius;
						tri->bounds[1][1] = mid[1] + radius;
						tri->bounds[1][2] = mid[2] + radius;*/
					}

					// add to the model bounds
					_bounds.AddBounds(surf.Geometry.Bounds);
				}
			}
		}
Beispiel #44
0
		public idClipModel(idClipModel model)
		{
			_id = model.ID;
			_owner = model.Owner;
			
			_enabled = model.Enabled;
			_entity = model.Entity;

			_origin = model.Origin;
			_axis = model.Axis;
			_bounds = model.Bounds;
			_absBounds = model.AbsoluteBounds;

			_material = model.Material;
			_contents = model.Contents;
			_collisionModelHandle = model.CollisionModelHandle;
			_traceModelCache = null;

			if(model.TraceModelCache != null)
			{
				idConsole.Warning("TODO: LoadModel( *GetCachedTraceModel( model->traceModelIndex ) );");
			}

			_renderModelHandle = model.RenderModelHandle;
			_touchCount = -1;
		}
Beispiel #45
0
 public idRenderEntity()
 {
     _parameters      = new RenderEntityComponent();
     _modelMatrix     = Matrix.Identity;
     _referenceBounds = idBounds.Zero;
 }
		public override void InitEmpty(string name)
		{
			if(this.Disposed == true)
			{
				throw new ObjectDisposedException(this.GetType().Name);
			}

			// model names of the form _area* are static parts of the
			// world, and have already been considered for optimized shadows
			// other model names are inline entity models, and need to be
			// shadowed normally
			_isStaticWorldModel = (name.StartsWith("_area") == true);

			_name = name;
			_reloadable = false; // if it didn't come from a file, we can't reload it

			Purge();

			_purged = false;
			_bounds = idBounds.Zero;
		}
Beispiel #47
0
		private void InitDefaultPhysics(Vector3 origin, Matrix axis)
		{
			string temp = _spawnArgs.GetString("clipmodel", "");
			idClipModel clipModel = null;

			// check if a clipmodel key/value pair is set
			if(temp != string.Empty)
			{
				if(idClipModel.CheckModel(temp) != null)
				{
					clipModel = new idClipModel(temp);
				}
			}

			if(_spawnArgs.GetBool("noclipmodel", false) == false)
			{
				// check if mins/maxs or size key/value pairs are set
				if(clipModel == null)
				{
					idBounds bounds = idBounds.Zero;
					bool setClipModel = false;

					if((_spawnArgs.ContainsKey("mins") == true)
						&& (_spawnArgs.ContainsKey("maxs") == true))
					{
						bounds = new idBounds(_spawnArgs.GetVector3("mins"), _spawnArgs.GetVector3("maxs"));
						setClipModel = true;

						if((bounds.Min.X > bounds.Max.X)
							|| (bounds.Min.Y > bounds.Max.Y)
							|| (bounds.Min.Z > bounds.Max.Z))
						{
							idConsole.Error("Invalid bounds '{0}'-'{1}' on entity '{2}'", bounds.Min, bounds.Max, this.Name);
						}
					}
					else if(_spawnArgs.ContainsKey("size") == true)
					{
						Vector3 size = _spawnArgs.GetVector3("size");

						if((size.X < 0.0f)
							|| (size.Y < 0.0f)
							|| (size.Z < 0.0f))
						{
							idConsole.Error("Invalid size '{0}' on entity '{1}'", size, this.Name);
						}

						setClipModel = true;
						bounds = new idBounds(
									new Vector3(size.X * -0.5f, size.Y * -0.5f, 0.0f),
									new Vector3(size.X * 0.5f, size.Y * 0.5f, size.Z)
								);
					}

					if(setClipModel == true)
					{
						int sideCount = _spawnArgs.GetInteger("cyclinder", 0);

						idTraceModel traceModel = new idTraceModel();

						if(sideCount > 0)
						{
							idConsole.Warning("TODO: traceModel.SetupCyclinder(bounds, (sideCount < 3) ? 3 : sideCount);");
						}
						else if((sideCount = _spawnArgs.GetInteger("cone", 0)) > 0)
						{
							idConsole.Warning("TODO: traceModel.SetupCone(bounds, (sideCount < 3) ? 3 : sideCount);");
						}
						else
						{
							traceModel.SetupBox(bounds);
						}

						clipModel = new idClipModel(traceModel);
					}
				}

				// check if the visual model can be used as collision model
				if(clipModel == null)
				{
					temp = _spawnArgs.GetString("model");

					if(temp != string.Empty)
					{
						if(idClipModel.CheckModel(temp) != null)
						{
							clipModel = new idClipModel(temp);
						}
					}
				}
			}

			_defaultPhysicsObject.Self = this;
			_defaultPhysicsObject.SetClipModel(clipModel, 1.0f);
			_defaultPhysicsObject.SetOrigin(origin);
			_defaultPhysicsObject.SetAxis(axis);

			_physics = _defaultPhysicsObject;
		}
		private void GetNodeBounds_R(ref idBounds bounds, CollisionModelNode node)
		{
			while(true)
			{
				foreach(CollisionModelPolygon poly in node.Polygons)
				{
					bounds.AddPoint(poly.Bounds.Min);
					bounds.AddPoint(poly.Bounds.Max);
				}

				foreach(CollisionModelBrush brush in node.Brushes)
				{
					bounds.AddPoint(brush.Bounds.Min);
					bounds.AddPoint(brush.Bounds.Max);
				}

				if(node.PlaneType == -1)
				{
					break;
				}

				GetNodeBounds_R(ref bounds, node.Children[1]);
				node = node.Children[0];
			}
		}
Beispiel #49
0
		public bool GetBounds(out idBounds bounds, int animNumber, int currentTime, int cycleCount)
		{
			if(_anims[animNumber] == null)
			{
				bounds = idBounds.Zero;
				return false;
			}

			bounds = _anims[animNumber].GetBounds(currentTime, cycleCount);

			return true;
		}
		private bool InsideAllChildren(CollisionModelNode node, idBounds bounds)
		{
			if(node.PlaneType != -1)
			{
				float v = (node.PlaneType == 0) ? bounds.Min.X : (node.PlaneType == 1) ? bounds.Min.Y : bounds.Min.Z;
				float v2 = (node.PlaneType == 0) ? bounds.Max.X : (node.PlaneType == 1) ? bounds.Max.Y : bounds.Max.Z;

				if(v >= node.PlaneDistance)
				{
					return false;
				}
				else if(v2 <= node.PlaneDistance)
				{
					return false;
				}
				else if(InsideAllChildren(node.Children[0], bounds) == false)
				{
					return false;
				}
				else if(InsideAllChildren(node.Children[1], bounds) == false)
				{
					return false;
				}
			}

			return true;
		}
Beispiel #51
0
		/// <summary>
		/// Axial bounding box.
		/// </summary>
		/// <param name="boxBounds"></param>
		public idTraceModel(idBounds boxBounds)
		{
			InitBox();
			SetupBox(boxBounds);
		}
Beispiel #52
0
		public void Link(idClip clip, idEntity entity, int newID, Vector3 newOrigin, Matrix newAxis, int renderModelHandle)
		{
			if(this.Disposed == true)
			{
				throw new ObjectDisposedException("idClipModel");
			}

			_entity = entity;
			_id = newID;
			_origin = newOrigin;
			_axis = newAxis;

			if(_renderModelHandle != -1)
			{
				_renderModelHandle = renderModelHandle;

				RenderEntityComponent renderEntity = idR.Game.RenderWorld.GetRenderEntity(renderModelHandle);

				if(renderEntity != null)
				{
					_bounds = renderEntity.Bounds;
				}
			}

			Link(clip);
		}
Beispiel #53
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 #54
0
		private void ConstrainViewFrustum()
		{
			idBounds bounds = new idBounds();

			// constrain the view frustum to the total bounds of all visible lights and visible entities
			
			// TODO: lights
			/*for(viewLight_t* vLight = tr.viewDef->viewLights; vLight; vLight = vLight->next)
			{
				bounds.AddBounds(vLight->lightDef->frustumTris->bounds);
			}*/
				
			foreach(ViewEntity viewEntity in _viewDefinition.ViewEntities)
			{
				bounds.AddBounds(viewEntity.EntityDef.ReferenceBounds);
			}
			
			_viewDefinition.ViewFrustum.ConstrainToBounds(bounds);

			float farDistance = idE.CvarSystem.GetFloat("r_useFrustumFarDistance");

			if(farDistance > 0.0f)
			{
				_viewDefinition.ViewFrustum.MoveFarDistance(farDistance);
			}
		}