Entities that are expensive to generate, like skeletal models, can be deferred until their bounds are found to be in view, in the frustum of a shadowing light that is in view, or contacted by a trace / overlay test. This is also used to do visual cueing on items in the view The renderView may be NULL if the callback is being issued for a non-view related source. The callback function should clear renderEntity->callback if it doesn't want to be called again next time the entity is referenced (ie, if the callback has now made the entity valid until the next updateEntity)
		public override idBounds GetBounds(RenderEntityComponent renderEntity = null)
		{
			if(this.Disposed == true)
			{
				throw new ObjectDisposedException(this.GetType().Name);
			}

			return _particleSystem.Bounds;
		}
Beispiel #2
0
		private int	_pvsAreaCount;			// number of renderer areas the entity covers
		#endregion

		#region Constructor
		public idEntity()
		{
			_entityIndex = idR.MaxGameEntities - 1;
			_entityDefIndex = -1;

			_className = "unknown";

			_renderEntity = new RenderEntityComponent();
			_defaultPhysicsObject = new idPhysics_Static();

			idConsole.Warning("TODO: idEntity");
			/*			
			snapshotNode.SetOwner(this);
			snapshotSequence = -1;*/
	
			/*
			bindJoint = INVALID_JOINT;*/
			_bindBody = -1;

			/*memset(PVSAreas, 0, sizeof(PVSAreas));*/
			_pvsAreaCount = -1;

			_flags.NeverDormant = true; // most entities never go dormant

			/* mpGUIState = -1;*/
		}
Beispiel #3
0
		public virtual void Spawn()
		{
			if(this.Disposed == true)
			{
				throw new ObjectDisposedException(this.GetType().Name);
			}

			idConsole.WriteLine("TODO: idEntity.Spawn");
			/*int					i;
			const char			*temp;
			idVec3				origin;
			idMat3				axis;
			const idKeyValue	*networkSync;
			const char			*classname;
			const char			*scriptObjectName;*/

			idR.Game.RegisterEntity(this);

			_className = _spawnArgs.GetString("classname", null);

			idDeclEntity def = idR.Game.FindEntityDef(_className, false);

			if(def != null)
			{
				_entityDefIndex = def.Index;
			}

			/*
			TODO
			FixupLocalizedStrings();
			*/

			// parse static models the same way the editor display does
			_renderEntity = idR.GameEdit.ParseSpawnArgsToRenderEntity(_spawnArgs);
			_renderEntity.EntityIndex = this.Index;

			// TODO
			/*
					// go dormant within 5 frames so that when the map starts most monsters are dormant
					dormantStart = gameLocal.time - DELAY_DORMANT_TIME + gameLocal.msec * 5;*/

			/*

			// do the audio parsing the same way dmap and the editor do
			gameEdit->ParseSpawnArgsToRefSound( &spawnArgs, &refSound );

			// only play SCHANNEL_PRIVATE when sndworld->PlaceListener() is called with this listenerId
			// don't spatialize sounds from the same entity
			refSound.listenerId = entityNumber + 1;

			cameraTarget = NULL;
			temp = spawnArgs.GetString( "cameraTarget" );
			if ( temp && temp[0] ) {
				// update the camera taget
				PostEventMS( &EV_UpdateCameraTarget, 0 );
			}

			for ( i = 0; i < MAX_RENDERENTITY_GUI; i++ ) {
				UpdateGuiParms( renderEntity.gui[ i ], &spawnArgs );
			}*/

			_flags.SolidForTeam = _spawnArgs.GetBool("solidForTeam", false);
			_flags.NeverDormant = _spawnArgs.GetBool("neverDormant", false);
			_flags.Hidden = _spawnArgs.GetBool("hide", false);

			if(_flags.Hidden == true)
			{
				// make sure we're hidden, since a spawn function might not set it up right
				idConsole.Warning("TODO: PostEventMS( &EV_Hide, 0 );");
			}
			/*cinematic = spawnArgs.GetBool( "cinematic", "0" );

			networkSync = spawnArgs.FindKey( "networkSync" );
			if ( networkSync ) {
				fl.networkSync = ( atoi( networkSync->GetValue() ) != 0 );
			}
		*/

			// every object will have a unique name
			this.Name = _spawnArgs.GetString("name", string.Format("{0}_{1}_{2}", this.ClassName, _spawnArgs.GetString("classname"), this.Index));

			// if we have targets, wait until all entities are spawned to get them
			// TODO
			/*if ( spawnArgs.MatchPrefix( "target" ) || spawnArgs.MatchPrefix( "guiTarget" ) ) {
				if ( gameLocal.GameState() == GAMESTATE_STARTUP ) {
					PostEventMS( &EV_FindTargets, 0 );
				} else {
					// not during spawn, so it's ok to get the targets
					FindTargets();
				}
			}*/

			_health = _spawnArgs.GetInteger("health");

			Vector3 origin = _renderEntity.Origin;
			Matrix axis = _renderEntity.Axis;
			
			InitDefaultPhysics(origin, axis);

			this.Origin = origin;
			this.Axis = axis;

			string temp = _spawnArgs.GetString("model");

			if(temp != string.Empty)
			{
				this.SetModel(temp);
			}

			if(_spawnArgs.GetString("bind", string.Empty) == string.Empty)
			{
				idConsole.Warning("TODO: PostEventMS( &EV_SpawnBind, 0 );");
			}

			// auto-start a sound on the entity
			// TODO
			/*if ( refSound.shader && !refSound.waitfortrigger ) {
				StartSoundShader( refSound.shader, SND_CHANNEL_ANY, 0, false, NULL );
			}*/

			// setup script object
			string scriptObjectName = _spawnArgs.GetString("scriptobject", string.Empty);

			if((this.ShouldConstructScriptObjectAtSpawn == true) && (scriptObjectName != string.Empty))
			{
				idConsole.Warning("TODO: script object");
				/*if ( !scriptObject.SetType( scriptObjectName ) ) {
					gameLocal.Error( "Script object '%s' not found on entity '%s'.", scriptObjectName, name.c_str() );
				}

				ConstructScriptObject();*/
			}
		}
		public idRenderEntity()
		{
			_parameters = new RenderEntityComponent();
			_modelMatrix = Matrix.Identity;
			_referenceBounds = idBounds.Zero;
		}
Beispiel #5
0
		/// <summary>
		/// 
		/// </summary>
		/// <remarks>
		/// Dynamic models should return a fast, conservative approximation.
		/// Static models should usually return the exact value.
		/// </remarks>
		/// <param name="renderEntity"></param>
		/// <returns></returns>
		public abstract idBounds GetBounds(RenderEntityComponent renderEntity = null);
Beispiel #6
0
		private void EmitSurface(GuiModelSurface surface, Matrix modelMatrix, Matrix modelViewMatrix, bool depthHack)
		{
			if(surface.VertexCount == 0)
			{
				// nothing in the surface
				return;
			}

			// copy verts and indexes
			Surface tri = new Surface();
			tri.Indexes = new int[surface.IndexCount];
			tri.Vertices = new Vertex[surface.VertexCount];

			_indexes.CopyTo(surface.FirstIndex, tri.Indexes, 0, surface.IndexCount);

			// we might be able to avoid copying these and just let them reference the list vars
			// but some things, like deforms and recursive
			// guis, need to access the verts in cpu space, not just through the vertex range
			_vertices.CopyTo(surface.FirstVertex, tri.Vertices, 0, surface.VertexCount);

			// move the verts to the vertex cache
			tri.AmbientCache = idE.RenderSystem.AllocateVertexCacheFrameTemporary(tri.Vertices);

			// if we are out of vertex cache, don't create the surface
			if(tri.AmbientCache == null)
			{
				return;
			}

			RenderEntityComponent renderEntity = new RenderEntityComponent();
			renderEntity.MaterialParameters[0] = surface.Color.X;
			renderEntity.MaterialParameters[1] = surface.Color.Y;
			renderEntity.MaterialParameters[2] = surface.Color.Z;
			renderEntity.MaterialParameters[3] = surface.Color.W;

			ViewEntity guiSpace = new ViewEntity();
			guiSpace.ModelMatrix = modelMatrix;
			guiSpace.ModelViewMatrix = modelViewMatrix;
			guiSpace.WeaponDepthHack = depthHack;

			// add the surface, which might recursively create another gui
			idE.RenderSystem.AddDrawSurface(tri, guiSpace, renderEntity, surface.Material, idE.RenderSystem.ViewDefinition.Scissor);
		}
Beispiel #7
0
		/// <summary>
		/// Does not write to the demo file, which will only be updated for visible entities.
		/// </summary>
		/// <param name="index"></param>
		/// <param name="renderComponent"></param>
		public void UpdateEntityDefinition(int index, RenderEntityComponent renderComponent)
		{
			if(idE.CvarSystem.GetBool("r_skipUpdates") == true)
			{
				return;
			}

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

			if((renderComponent.Model == null) && (renderComponent.Callback == null))
			{
				idConsole.Error("idRenderWorld::UpdateEntityDefinition: NULL model");
			}

			// create new slots if needed
			if((index < 0) || (index > idE.LudicrousEntityIndex))
			{
				idConsole.Error("idRenderWorld::UpdateEntityDefinitionL index = {0}", index);
			}

			while(index >= _entityDefinitions.Count)
			{
				_entityDefinitions.Add(null);
			}

			idRenderEntity def = _entityDefinitions[index];

			if(def != null)
			{
				if(renderComponent.ForceUpdate == false)
				{
					idConsole.Warning("TODO: force update - quite important!");

					/*// check for exact match (OPTIMIZE: check through pointers more)
					if ( !re->joints && !re->callbackData && !def->dynamicModel && !memcmp( re, &def->parms, sizeof( *re ) ) ) {
						return;
					}

					// if the only thing that changed was shaderparms, we can just leave things as they are
					// after updating parms

					// if we have a callback function and the bounds, origin, axis and model match,
					// then we can leave the references as they are
					if ( re->callback ) {

						bool axisMatch = ( re->axis == def->parms.axis );
						bool originMatch = ( re->origin == def->parms.origin );
						bool boundsMatch = ( re->bounds == def->referenceBounds );
						bool modelMatch = ( re->hModel == def->parms.hModel );

						if ( boundsMatch && originMatch && axisMatch && modelMatch ) {
							// only clear the dynamic model and interaction surfaces if they exist
							c_callbackUpdate++;
							R_ClearEntityDefDynamicModel( def );
							def->parms = *re;
							return;
						}
					}*/
				}

				// save any decals if the model is the same, allowing marks to move with entities
				if(def.Parameters.Model == renderComponent.Model)
				{
					FreeEntityDefDerivedData(def, true, true);
				}
				else
				{
					FreeEntityDefDerivedData(def, false, false);
				}
			}
			else
			{
				// creating a new one
				def = new idRenderEntity();
				_entityDefinitions[index] = def;

				def.World = this;
				def.EntityIndex = index;
			}

			def.Parameters = renderComponent;
			def.ModelMatrix = idHelper.AxisToModelMatrix(def.Parameters.Axis, def.Parameters.Origin);
			def.LastModifiedFrameNumber = idE.RenderSystem.FrameCount;

			// TODO: demo
			/*if ( session->writeDemo && def->archived ) {
				WriteFreeEntity( entityHandle );
				def->archived = false;
			}*/

			// optionally immediately issue any callbacks
			if((idE.CvarSystem.GetBool("r_useEntityCallbacks") == false) && (def.Parameters.Callback != null))
			{
				idConsole.Warning("TODO: R_IssueEntityDefCallback( def );");
			}

			// based on the model bounds, add references in each area
			// that may contain the updated surface
			CreateEntityReferences(def);
		}
		/// <summary>
		/// Calculates a rough bounds by using the joint radii without
		/// transforming all the points.
		/// </summary>
		/// <param name="renderEntity"></param>
		/// <returns></returns>
		public override idBounds GetBounds(RenderEntityComponent renderEntity = null)
		{ 
			if(this.Disposed == true)
			{
				throw new ObjectDisposedException(this.GetType().Name);
			}

			if(renderEntity == null)
			{
				// this is the bounds for the reference pose
				return _bounds;
			}

			return renderEntity.Bounds;
		}
Beispiel #9
0
		/// <summary>
		/// Does not write to the demo file, which will only be updated for visible entities.
		/// </summary>
		/// <param name="index"></param>
		/// <param name="renderComponent"></param>
		public void UpdateEntityDefinition(idRenderEntity renderEntity, RenderEntityComponent renderComponent)
		{
			UpdateEntityDefinition(_entityDefinitions[_entityDefinitions.IndexOf(renderEntity)], renderComponent);
		}
Beispiel #10
0
		public idRenderEntity AddEntityDefinition(RenderEntityComponent renderComponent)
		{
			// try and reuse a free spot
			int index = _entityDefinitions.FindIndex(x => x == null);

			if(index == -1)
			{
				index = _entityDefinitions.Count;
				_entityDefinitions.Add(null);

				idConsole.Warning("TODO: ResizeInteractionTable");
				/*if ( interactionTable && entityDefs.Num() > interactionTableWidth ) {
					ResizeInteractionTable();
				}*/
			}

			UpdateEntityDefinition(index, renderComponent);

			return _entityDefinitions[index];
		}
Beispiel #11
0
		private void PreRender()
		{
			if(_needsRender == true)
			{
				_world.InitFromMap(null);

				idDict spawnArgs = new idDict();
				spawnArgs.Set("classname", "light");
				spawnArgs.Set("name", "light_1");
				spawnArgs.Set("origin", _lightOrigin);
				spawnArgs.Set("_color", _lightColor);

				idConsole.Warning("TODO: lighting");
			
				/*gameEdit->ParseSpawnArgsToRenderLight(&spawnArgs, &rLight);
				lightDef = world->AddLightDef(&rLight);
				if(!modelName[0])
				{
					common->Warning("Window '%s' in gui '%s': no model set", GetName(), GetGui()->GetSourceFile());
				}*/

				spawnArgs.Clear();
				spawnArgs.Set("classname", "func_static");
				spawnArgs.Set("model", _modelName);
				spawnArgs.Set("origin", _modelOrigin);

				_worldEntity = idE.GameEdit.ParseSpawnArgsToRenderEntity(spawnArgs);

				if(_worldEntity.Model != null)
				{
					Vector3 v = _modelRotate.ToVector3();

					_worldEntity.Axis = v.ToMatrix();
					_worldEntity.MaterialParameters[0] = 1;
					_worldEntity.MaterialParameters[0] = 1;
					_worldEntity.MaterialParameters[0] = 1;
					_worldEntity.MaterialParameters[0] = 1;

					_renderEntity = _world.AddEntityDefinition(_worldEntity);
				}

				_needsRender.Set(false);
			}
		}
Beispiel #12
0
		public override RenderEntityComponent ParseSpawnArgsToRenderEntity(idDict args)
		{
			RenderEntityComponent renderEntity = new RenderEntityComponent();
			idDeclModel modelDef = null;
			
			string temp = args.GetString("model");

			if(temp != string.Empty)
			{
				modelDef = idE.DeclManager.FindType<idDeclModel>(DeclType.ModelDef, temp, false);

				if(modelDef != null)
				{
					renderEntity.Model = modelDef.Model;
				}

				if(renderEntity.Model == null)
				{
					renderEntity.Model = idE.RenderModelManager.FindModel(temp);
				}
			}

			if(renderEntity.Model != null)
			{
				renderEntity.Bounds = renderEntity.Model.GetBounds(renderEntity);
			}
			else
			{
				renderEntity.Bounds = new idBounds();
			}

			temp = args.GetString("skin");

			if(temp != string.Empty)
			{
				renderEntity.CustomSkin = idR.DeclManager.FindSkin(temp);
			}
			else if(modelDef != null)
			{
				renderEntity.CustomSkin = modelDef.DefaultSkin;
			}

			temp = args.GetString("shader");

			if(temp != null)
			{
				renderEntity.CustomMaterial = idR.DeclManager.FindMaterial(temp);
			}

			renderEntity.Origin = args.GetVector3("origin", Vector3.Zero);

			// get the rotation matrix in either full form, or single angle form
			renderEntity.Axis = args.GetMatrix("rotation", "1 0 0 0 1 0 0 0 1");

			if(renderEntity.Axis == Matrix.Identity)
			{
				float angle = args.GetFloat("angle");

				if(angle != 0.0f)
				{
					renderEntity.Axis = new idAngles(0.0f, angle, 0.0f).ToMatrix();
				}
				else
				{
					renderEntity.Axis = Matrix.Identity;
				}
			}

			// TODO:
			//renderEntity.ReferencedSound = null;

			// get shader parms
			Vector3 color = args.GetVector3("_color", new Vector3(1, 1, 1));

			float[] materialParms = renderEntity.MaterialParameters;

			materialParms[(int) MaterialParameter.Red] = color.X;
			materialParms[(int) MaterialParameter.Green] = color.Y;
			materialParms[(int) MaterialParameter.Blue] = color.Z;

			materialParms[3] = args.GetFloat("shaderParm3", 1);
			materialParms[4] = args.GetFloat("shaderParm4", 0);
			materialParms[5] = args.GetFloat("shaderParm5", 0);
			materialParms[6] = args.GetFloat("shaderParm6", 0);
			materialParms[7] = args.GetFloat("shaderParm7", 0);
			materialParms[8] = args.GetFloat("shaderParm8", 0);
			materialParms[9] = args.GetFloat("shaderParm9", 0);
			materialParms[10] = args.GetFloat("shaderParm10", 0);
			materialParms[11] = args.GetFloat("shaderParm11", 0);

			renderEntity.MaterialParameters = materialParms;

			// check noDynamicInteractions flag
			renderEntity.NoDynamicInteractions = args.GetBool("noDynamicInteractions");

			// check noshadows flag
			renderEntity.NoShadow = args.GetBool("noshadows");

			// check noselfshadows flag
			renderEntity.NoSelfShadow = args.GetBool("noselfshadows");

			// init any guis, including entity-specific states
			int count = renderEntity.Gui.Length;

			for(int i = 0; i < count; i++)
			{
				temp = args.GetString(i == 0 ? "gui" : string.Format("gui{0}", i + 1));

				if(temp != null)
				{
					renderEntity.Gui[i] = AddRenderGui(temp, args);
				}
			}

			return renderEntity;
		}		
Beispiel #13
0
		public void AddDrawSurface(Surface surface, ViewEntity space, RenderEntityComponent renderEntity, idMaterial material, idScreenRect scissor)
		{
			float[] materialParameters;
			float[] referenceRegisters = new float[idE.MaxExpressionRegisters];
			float[] generatedMaterialParameters = new float[idE.MaxEntityMaterialParameters];

			DrawSurface drawSurface = new DrawSurface();
			drawSurface.Geometry = surface;
			drawSurface.Space = space;
			drawSurface.Material = material;
			drawSurface.ScissorRectangle = scissor;
			drawSurface.Sort = (float) material.Sort + _sortOffset;

			// bumping this offset each time causes surfaces with equal sort orders to still
			// deterministically draw in the order they are added
			_sortOffset += 0.000001f;

			// process the shader expressions for conditionals / color / texcoords
			float[] constantRegisters = material.ConstantRegisters;

			if(constantRegisters != null)
			{
				// shader only uses constant values
				drawSurface.MaterialRegisters = constantRegisters;
			}
			else
			{
				drawSurface.MaterialRegisters = new float[material.RegisterCount];

				// a reference shader will take the calculated stage color value from another shader
				// and use that for the parm0-parm3 of the current shader, which allows a stage of
				// a light model and light flares to pick up different flashing tables from
				// different light shaders				
				if(renderEntity.ReferenceMaterial != null)
				{
					// evaluate the reference shader to find our shader parms
					//renderEntity.ReferenceMaterial.EvaluateRegisters(ref referenceRegisters, renderEntity.MaterialParameters, this.ViewDefinition, renderEntity.ReferenceSound);

					idConsole.Warning("TODO: ref material");
					/*MaterialStage stage = renderEntity.ReferenceMaterial.GetStage(0);

					memcpy( generatedShaderParms, renderEntity->shaderParms, sizeof( generatedShaderParms ) );
					generatedShaderParms[0] = refRegs[ pStage->color.registers[0] ];
					generatedShaderParms[1] = refRegs[ pStage->color.registers[1] ];
					generatedShaderParms[2] = refRegs[ pStage->color.registers[2] ];*/

					materialParameters = generatedMaterialParameters;
				} 
				else
				{
					// evaluate with the entityDef's shader parms
					materialParameters = renderEntity.MaterialParameters;
				}

				float oldFloatTime = 0;
				int oldTime = 0;

				if((space.EntityDef != null) && (space.EntityDef.Parameters.TimeGroup != 0))
				{
					oldFloatTime = this.ViewDefinition.FloatTime;
					oldTime = this.ViewDefinition.RenderView.Time;

					this.ViewDefinition.FloatTime = idE.Game.GetTimeGroupTime(space.EntityDef.Parameters.TimeGroup) * 0.001f;
					this.ViewDefinition.RenderView.Time = idE.Game.GetTimeGroupTime(space.EntityDef.Parameters.TimeGroup);
				}

				material.EvaluateRegisters(ref drawSurface.MaterialRegisters, materialParameters, idE.RenderSystem.ViewDefinition /* TODO: ,renderEntity->referenceSound*/);

				if((space.EntityDef != null) && (space.EntityDef.Parameters.TimeGroup != 0))
				{
					this.ViewDefinition.FloatTime = oldFloatTime;
					this.ViewDefinition.RenderView.Time = oldTime;
				}
			}

			// check for deformations
			// TODO: R_DeformDrawSurf( drawSurf );

			// skybox surfaces need a dynamic texgen
			// TODO: skybox
			/*switch( shader->Texgen() ) {
				case TG_SKYBOX_CUBE:
					R_SkyboxTexGen( drawSurf, tr.viewDef->renderView.vieworg );
					break;
				case TG_WOBBLESKY_CUBE:
					R_WobbleskyTexGen( drawSurf, tr.viewDef->renderView.vieworg );
					break;
			}*/

			// check for gui surfaces
			// TODO: gui surface
			idUserInterface	gui = null;

			if(space.EntityDef == null)
			{
				gui = material.GlobalInterface;
			}
			else
			{
				idConsole.Warning("TODO: global gui");
				/*int guiNum = shader->GetEntityGui() - 1;
				if ( guiNum >= 0 && guiNum < MAX_RENDERENTITY_GUI ) {
					gui = renderEntity->gui[ guiNum ];
				}
				if ( gui == NULL ) {
					gui = shader->GlobalGui();
				}*/
			}

			if(gui != null)
			{
				// force guis on the fast time
				float oldFloatTime = this.ViewDefinition.FloatTime;
				int oldTime = this.ViewDefinition.RenderView.Time;

				this.ViewDefinition.FloatTime = idE.Game.GetTimeGroupTime(1) * 0.001f;
				this.ViewDefinition.RenderView.Time = idE.Game.GetTimeGroupTime(1);

				idBounds ndcBounds;

				idConsole.Warning("TODO: precise cull + render gui surface");

				/*if ( !R_PreciseCullSurface( drawSurf, ndcBounds ) ) {
					// did we ever use this to forward an entity color to a gui that didn't set color?
		//			memcpy( tr.guiShaderParms, shaderParms, sizeof( tr.guiShaderParms ) );
					R_RenderGuiSurf( gui, drawSurf );
				}*/

				this.ViewDefinition.FloatTime = oldFloatTime;
				this.ViewDefinition.RenderView.Time = oldTime;
			}

			_viewDefinition.DrawSurfaces.Add(drawSurface);

			// we can't add subviews at this point, because that would
			// increment tr.viewCount, messing up the rest of the surface
			// adds for this view
		}