Exemplo n.º 1
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;
		}
Exemplo n.º 2
0
		/// <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);
				}
			}
		}
Exemplo n.º 3
0
		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;
			}
		}
Exemplo n.º 4
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;
		}
Exemplo n.º 5
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;
		}
Exemplo n.º 6
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;
		}
Exemplo n.º 7
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;
		}
		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;
		}
Exemplo n.º 9
0
		/// <summary>
		/// Axial bounding box.
		/// </summary>
		/// <param name="boxBounds"></param>
		public idTraceModel(idBounds boxBounds)
		{
			InitBox();
			SetupBox(boxBounds);
		}
Exemplo n.º 10
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);
		}
Exemplo n.º 11
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;
		}
Exemplo n.º 12
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;
		}
Exemplo n.º 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);
		}
Exemplo n.º 14
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;
		}
Exemplo n.º 15
0
		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;
		}
Exemplo n.º 16
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;
		}
		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];
			}
		}
Exemplo n.º 18
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 );
Exemplo n.º 20
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);
		}
Exemplo n.º 21
0
		public idRenderEntity()
		{
			_parameters = new RenderEntityComponent();
			_modelMatrix = Matrix.Identity;
			_referenceBounds = idBounds.Zero;
		}
Exemplo n.º 22
0
		public void LoadModel(idTraceModel traceModel)
		{
			if(this.Disposed == true)
			{
				throw new ObjectDisposedException("idClipModel");
			}

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

			_bounds = traceModel.Bounds;
		}
Exemplo n.º 23
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;
		}
Exemplo n.º 24
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);
			}
		}