//--------------------------------------------------------------------------------------------------------------------------------------------------- // <copyright file="Statics.cs" company="DarkWynter Studios"> // Copyright (C)2007 DarkWynter Studios. All rights reserved. // </copyright> //--------------------------------------------------------------------------------------------------------------------------------------------------- // {Contact : darkwynter.com for licensing information //--------------------------------------------------------------------------------------------------------------------------------------------------- #define forPC namespace DarkWynterEngine.ObjectLib { #region Using Statements using System; using System.Collections.Generic; using Microsoft.Xna.Framework; using Microsoft.Xna.Framework.Audio; using Microsoft.Xna.Framework.Content; using Microsoft.Xna.Framework.Graphics; using Microsoft.Xna.Framework.Input; using Microsoft.Xna.Framework.Storage; using System.Xml; using System.Diagnostics; using System.Threading; #endregion using Audio; using Physics; using Globals; using GameObjects; using PhysicsGpu; using Draw; /// <summary> /// Container and Manager class for GameObjects /// </summary> public class ObjectLibrary { #region Attributes /// <summary> /// Contains all the Type definitions for GameObjects /// </summary> public List<GameObjectTypes> gameObjectTypes; // STANDARD OBJECTS ================================================= /// <summary> /// Terrain object. /// </summary> public Terrain terrain; /// <summary> /// A list of all Human Players /// </summary> public List<Human> humans; /// <summary> /// A list of opponent AI Players /// </summary> public List<AI> bots; // GENERIC OBJECTS ================================================= /// <summary> /// Billboards requested by GameObjects /// </summary> private List<BillboardList> billboards; /// <summary> /// User Supplied GameObjects /// </summary> private List<GameObject> gameObjectList; /// <summary> /// Cpu-based Props Loaded from XML /// </summary> private List<PropList> propLists; /// <summary> /// Gpu-based Props Loaded from XML /// </summary> public List<GpuObjectList> gpuObjectLists; /// <summary> /// Keeps Model Information for Lists /// </summary> public ModelManager modelManager; /// <summary> /// Drawn on HUD to identify AI at a distance. /// </summary> private Texture2D enemyTargetReticle; #endregion #region Methods /// <summary> /// CONSTRUCTOR: /// </summary> public ObjectLibrary(List<GameObjectTypes> userDefinedTypes) { Statics.LevelSettings.darkMatterIterator = 0; if (Statics.LevelSettings.darkMatter == null) { Statics.LevelSettings.darkMatter = new List<Mass>(Statics.LevelSettings.darkMatterCount); for (int i = 0; i < Statics.LevelSettings.darkMatterCount; i++) { Statics.LevelSettings.darkMatter.Add(new Mass()); } } else { for (int i = 0; i < Statics.LevelSettings.darkMatterCount; i++) { Statics.LevelSettings.darkMatter[i].ClearValues(); } Statics.GameSettings.accelDueToGravity = Vector3.Zero; Statics.GameSettings.gravityForce = 0.0f; } // Load Engine and Game supplied GameObjectTypes gameObjectTypes = new List<GameObjectTypes>(); gameObjectTypes.Add(new GameObjectTypes()); gameObjectTypes.AddRange(userDefinedTypes); Statics.SystemSettings.TOTAL_PLAYERS = 0; humans = new List<Human>(); for (int playerNumber = 0; playerNumber < 4; playerNumber++) { humans.Add(new Human()); humans[playerNumber].playerIndex = playerNumber; } } /// <summary> /// Load the Terrain and Skysphere for the Terrain Demo /// </summary> public void LoadLevel() { // Load Level XML XML.LoadLevel(XML.levelInfo[0].filepath); // Create the model manager modelManager = new ModelManager(); // Terrain if (XML.gameObjectInfo.terrainNode != null) { terrain = new Terrain(); terrain.Load(XML.gameObjectInfo.terrainNode, this); } // Load Audio if (XML.gameObjectInfo.musicNode != null) { Audio.LoadXML(XML.gameObjectInfo.musicNode); } // Game Objects - Single Depth List gameObjectList = new List<GameObject>(); if (XML.gameObjectInfo.gameObjectNodes != null) { foreach (XmlNode objectNode in XML.gameObjectInfo.gameObjectNodes.ChildNodes) { GameObject gameObject = new GameObject(); if (!CreateGameObjectType(objectNode, ref gameObject)) { // GameObject could not be created continue; } if(gameObject.Load(objectNode, this)) { gameObjectList.Add(gameObject); } } } // Props - List of Lists propLists = new List<PropList>(); if (XML.gameObjectInfo.propNode != null) { foreach (XmlNode objectNode in XML.gameObjectInfo.propNode.ChildNodes) { PropList propList = new PropList(); if (propList.Load(objectNode, this)) { propLists.Add(propList); } } } // GpuObjects - List of Lists gpuObjectLists = new List<GpuObjectList>(); if (XML.gameObjectInfo.gpuObjectNodes != null) { foreach (XmlNode objectNode in XML.gameObjectInfo.gpuObjectNodes.ChildNodes) { GpuObjectList gpuObjectList = new GpuObjectList(); gpuObjectList.Load(objectNode, this); gpuObjectLists.Add(gpuObjectList); } } // Props Billboards - ( Dynamic GameObject Billboards handled in Draw_Billboards) billboards = new List<BillboardList>(); if (XML.gameObjectInfo.billboardNode != null) { foreach (XmlNode objectNode in XML.gameObjectInfo.billboardNode.ChildNodes) { BillboardList billboardList = new BillboardList(); billboardList.Load(objectNode, this); billboards.Add(billboardList); } } // Humans humans = new List<Human>(); if (XML.gameObjectInfo.humanNodes != null) { foreach (XmlNode objectNode in XML.gameObjectInfo.humanNodes.ChildNodes) { GameObject gameObject = new Human(); if (gameObject.Load(objectNode, this)) { humans.Add((Human)gameObject); } } } // Bots bots = new List<AI>(); if (XML.gameObjectInfo.botNodes != null) { int botCounter = 0; foreach (XmlNode objectNode in XML.gameObjectInfo.botNodes.ChildNodes) { if (botCounter < Statics.GameSettings.botCount) { GameObject gameObject = new AI(); if (gameObject.Load(objectNode, this)) { bots.Add((AI)gameObject); } botCounter++; } } } enemyTargetReticle = Statics.SystemSettings.content.Load<Texture2D>("Content/_textures/TargetMarker"); } /// <summary> /// Create an GameObject using the "type" string included in the XmlNode. /// User-Defined types can be added to the engine by inheriting from GameObjectTypes /// and overloading it's CreateGameobjectType method. This method must create a new /// GameObject and assign it to the incoming GameObject. Creation of the GameObject /// by the overloaded User-Defined class should use a case statement to decide what /// kind of GameObject to create based on the Xml-based "type" parameter. /// </summary> /// <param name="objectNode">Xml data describing the Gameobject.</param> /// <param name="gameObject">A blank GameObject to replace with User-Defined GameObject.</param> /// <returns>Returns true if GameObject was successfully created.</returns> public bool CreateGameObjectType(XmlNode objectNode, ref GameObject gameObject) { // Get the Object Type string type = objectNode.LocalName; for (int i = 0; i < gameObjectTypes.Count; i++) { // Try and create the gameObject bool found = gameObjectTypes[i].CreateGameObjectType(type, ref gameObject); if (found) { return true; } } return false; } /// <summary> /// Call all GameObject Updates to handle gravity and motion /// </summary> /// <param name="objectLibrary">ObjectLibrary</param> public void Update(ref ObjectLibrary objectLibrary, Collision collision) { // TEMP: Remove when LookupMap reinstalled List<Mass> collisionList = new List<Mass>(); for (int i = 0; i < gameObjectList.Count; i++) { collisionList.Add(gameObjectList[i].mass); } for (int i = 0; i < humans.Count; i++) { collisionList.Add(humans[i].mass); } for (int i = 0; i < bots.Count; i++) { collisionList.Add(bots[i].mass); } // END TEMP ============================ collision.UpdateCollision(ref objectLibrary, collisionList); // Modify terrain if changed terrain.Update(ref objectLibrary); // Update Dynamic Props, Particles, and Quads //Statics.lookupMap.UpdateDynamic(this); for (int i = 0; i < humans.Count; i++) { humans[i].Update(ref objectLibrary); } for (int i = 0; i < bots.Count; i++) { bots[i].Update(ref objectLibrary); } for (int i = 0; i < gameObjectList.Count; i++) { gameObjectList[i].Update(ref objectLibrary); } // Update Cpu Based Object Lists for (int i = 0; i < propLists.Count; i++) { propLists[i].Update(ref objectLibrary); } // Update Gpu Based Object Lists for (int i = 0; i < gpuObjectLists.Count; i++) { gpuObjectLists[i].Update(this); } } /// <summary> /// Remove a Game Object from our list of gameobjects /// </summary> /// <param name="gameObject">Game object to be removed</param> public void RemoveGameObject(GameObject gameObject) { gameObjectList.Remove(gameObject); } /// <summary> /// Player uses Attack Method to shoot Grenade-like objects onto the board /// </summary> /// <param name="playerID">ID of the player who fired the grenade</param> /// <param name="type">Type of grenade</param> /// <param name="initialPosition">Starting position of the grenade</param> /// <param name="direction">Normal direction of the grenade</param> /// <param name="particleMassValue">Mass of grenade</param> /// <param name="particleThermalValue">Thermal value of grenade</param> public void Attack_Grenade(int playerID, Enums.ParticleType type, Vector3 initialPosition, Vector3 direction, int particleMassValue, int particleThermalValue) { XmlNode particlesNode = XML.gameObjectInfo.particleNode; // Set it's properties Particle particle = new Particle(); particle.Load(particlesNode, this); particle.PrepAttack(playerID, type, initialPosition, direction, particleMassValue, particleThermalValue); gameObjectList.Add(particle); } /// <summary> /// Player uses Attack Method to shoot Bullet-like objects onto the board /// </summary> /// <param name="playerID">ID of the player who fired the Bullet</param> /// <param name="type">Type of Bullet</param> /// <param name="initialPosition">Starting position of the Bullet</param> /// <param name="direction">Normal direction of the Bullet</param> /// <param name="bulletMassValue">Mass of Bullet</param> /// <param name="bulletThermalValue">Thermal value of Bullet</param> public void Attack_Bullet(int playerID, Enums.BulletType type, Vector3 initialPosition, Vector3 direction, int bulletMassValue, int bulletThermalValue) { XmlNode bulletNode = XML.gameObjectInfo.bulletNode; // Set it's properties Bullet bullet = new Bullet(); bullet.Load(bulletNode, this); bullet.PrepAttack(playerID, type, initialPosition, direction, bulletMassValue, bulletThermalValue); gameObjectList.Add(bullet); } /// <summary> /// Player uses Attack Method to shoot Swarm-like objects onto the board /// </summary> /// <param name="playerID">ID of the player who fired the Swarm</param> /// <param name="initialPosition">Starting position of the Swarm</param> /// <param name="direction">Normal direction of the Swarm</param> /// <param name="swarmMassValue">Mass of Swarm</param> /// <param name="swarmThermalValue">Thermal value of Swarm</param> public void Attack_Swarm(int playerID, Vector3 initialPosition, Vector3 direction, int swarmMassValue, int swarmThermalValue) { XmlNode objectNode = XML.gameObjectInfo.gpuObjectNodes; objectNode = objectNode.FirstChild; // Create Object based on type matching in GameObjectTypes GameObject gameObject = new GameObject(); if (CreateGameObjectType(objectNode, ref gameObject)) { // Set up Model Manager string type = objectNode.Attributes["type"].Value; modelManager.AddNewModel(type, objectNode.Attributes["model"].Value, objectNode.Attributes["texture"].Value, objectNode.Attributes["bumpTexture"].Value); // Start Type properties gameObject.mass.gameObjectPointer = gameObject; gameObject.objectModelName = type; // Set Position gameObject.mass.SetPosition(initialPosition + (Statics.PlayerSettings.PARTICLE_START_DISTANCE * direction), initialPosition + ((Statics.PlayerSettings.PARTICLE_START_DISTANCE - 10) * direction)); //gameObject.mass.lastPosition = Vector3.Zero + initialPosition; gameObject.mass.boundingVolume = new BoundingVolume(new BoundingSphere(gameObject.mass.currentPosition, 2.0f)); // Set Direction //direction.Normalize(); //gameObject.mass.normalVector = Vector3.Zero + direction; gameObject.mass.velocity = Vector3.Zero; gameObject.mass.acceleration = Vector3.Zero; gameObject.mass.scale = new Vector3((int)(float.Parse(objectNode.Attributes["maxScale"].Value))); gameObject.mass.mass = float.Parse(objectNode.Attributes["mass"].Value); // Add Force gameObject.mass.AddForce(direction * 10000.0f); gameObject.objectValues = new VertexFogBinormalTangent(); gameObject.objectValues.Fog = new Vector4(gameObject.mass.scale, 0.0f); // Store the scale gameObject.objectValues.Binormal = new Vector4(gameObject.mass.currentRotation.X, gameObject.mass.currentRotation.Y, gameObject.mass.currentRotation.Z, gameObject.mass.currentRotation.W); // Store the quaternion rotation } // INSERT GPUOBJECTLIST ADD HERE..... gpuObjectLists[0].AddMass(gameObject.mass); } /// <summary> /// Draw and Postdrawing /// </summary> /// <param name="playerIndex">Player for which draw perspective is associated.</param> public void Draw(int playerIndex) { // Send Lighting to the Shader ShaderParameters.lightPosition0.SetValue(Statics.LevelSettings.lightPosition1); ShaderParameters.lightAmbient0.SetValue(Statics.LevelSettings.lightAmbient1); ShaderParameters.lightDiffuse0.SetValue(Statics.LevelSettings.lightDiffuse1); ShaderParameters.lightSpecular0.SetValue(Statics.LevelSettings.lightSpecular1); if (Statics.SystemSettings.singleLightSource) { ShaderParameters.lightPosition1.SetValue(Statics.LevelSettings.lightPosition1); ShaderParameters.lightAmbient1.SetValue(Statics.LevelSettings.lightAmbient1); ShaderParameters.lightDiffuse1.SetValue(Statics.LevelSettings.lightDiffuse1); ShaderParameters.lightSpecular1.SetValue(Statics.LevelSettings.lightSpecular1); } else { ShaderParameters.lightPosition1.SetValue(Statics.LevelSettings.lightPosition2); ShaderParameters.lightAmbient1.SetValue(Statics.LevelSettings.lightAmbient2); ShaderParameters.lightDiffuse1.SetValue(Statics.LevelSettings.lightDiffuse2); ShaderParameters.lightSpecular1.SetValue(Statics.LevelSettings.lightSpecular2); } ShaderParameters.fogEnd.SetValue(Statics.LevelSettings.fogEnd); ShaderParameters.fogStart.SetValue(Statics.LevelSettings.fogStart); // TerrainLOD and TerrainMod Shader Requisits Statics.PlayerSettings.playerPosition = humans[playerIndex].mass.currentPosition; Statics.PlayerSettings.playerLookVector = new Vector2(humans[playerIndex].mass.normalVector.X, humans[playerIndex].mass.normalVector.Z); Statics.PlayerSettings.playerRotation = humans[playerIndex].mass.currentRotation; Statics.TerrainSettings.terrainLookAtPoint = humans[playerIndex].lookAtPoint; Statics.TerrainSettings.terrainModRange = (int)(humans[playerIndex].attackMagnitude / 25); Statics.TerrainSettings.terrainModEnabled = humans[playerIndex].terrainModEnabled; // Draw the terrain if (Statics.SystemSettings.enableTerrainBumpMapping) { terrain.Draw(modelManager, "TerrainShaderMain"); } else { terrain.Draw(modelManager, "TerrainNoBumpsShaderMain"); } // Draw User Defined Game Objects for (int i = 0; i < gameObjectList.Count; i++) { gameObjectList[i].Draw(modelManager,"BasicLightingShaderMain"); } // Draw Cpu Based Object Lists for (int i = 0; i < propLists.Count; i++) { propLists[i].Draw(modelManager, "BasicLightingInstancedShaderMain"); } // Draw Gpu Based Object Lists for (int i = 0; i < gpuObjectLists.Count; i++) { gpuObjectLists[i].Draw(modelManager, "GPUPhysixInstancedShaderMain"); } //// Draw All Free Standing Billboards (Note: GameObject Billboards are drawn in DrawBillboards sequence) //for (int i = 0; i < billboards.Count; i++) //{ // billboards[i].Draw_Billboards(this, playerIndex); //} // Draw AI foreach (Player player in bots) { player.Draw(modelManager, ""); } // Draw Humans foreach (Player human in humans) { // if (human != humans[playerIndex]) //{ human.Draw(modelManager, ""); //} } // Draw AI Shields (NOTE: draw 2nd to last for transparency reasons) foreach (Player player in bots) { if (player.IsAlive()) { player.DrawShield(); } } // Draw Human Shields (NOTE: draw last for transparency reasons) foreach (Player player in humans) { if (player.IsAlive()) { player.DrawShield(); } } } /// <summary> /// Pass a Billboard List to GameObjects so they can add GameObject-relative Billboards. /// This does not effect the Prop Billboards. /// </summary> /// <param name="playerIndex">Billboards are oriented towards the Player we are drawing them for.</param> public void Draw_Billboards(int playerIndex) { // Create Empty List BillboardList dynamicBillboards = new BillboardList(); // Draw the terrain terrain.Draw_Billboards(this, dynamicBillboards); //// Draw Cpu Based Object Lists //for (int i = 0; i < propLists.Count; i++) //{ // propLists[i].Draw_Billboards(this, ref gameObjectBillboards); //} //// Draw Gpu Based Object Lists //for (int i = 0; i < gpuObjectLists.Count; i++) //{ // gpuObjectLists[i].Draw_Billboards(this, ref gameObjectBillboards); //} // Draw User Defined Game Objects for (int i = 0; i < gameObjectList.Count; i++) { gameObjectList[i].Draw_Billboards(this, dynamicBillboards); } // Draw Humans foreach (Player human in humans) { human.Draw_Billboards(this, dynamicBillboards); } // Draw AI foreach (Player player in bots) { player.Draw_Billboards(this, dynamicBillboards); } // Draw all GameObject Billboards dynamicBillboards.Draw_Billboards(this, playerIndex); } /// <summary> /// Let each GameObject draw it's own Sprites /// </summary> /// <param name="currentPlayerIndex">Current player's index</param> /// <param name="spriteBatch">SpriteBatch used to draw</param> public void PostDraw_HUD(int currentPlayerIndex, SpriteBatch spriteBatch) { // Calculate the player's ModelView Matrix Statics.RenderSettings.matrixView = Matrix.CreateLookAt(humans[currentPlayerIndex].mass.currentPosition, humans[currentPlayerIndex].mass.currentPosition + humans[currentPlayerIndex].mass.normalVector, humans[currentPlayerIndex].mass.upVector); // Calculate the player's Projection Matrix Statics.RenderSettings.matrixProjection = Matrix.CreatePerspectiveFieldOfView((float)Math.PI / 4, Statics.RenderSettings.cameraList[currentPlayerIndex].viewport.Width / Statics.RenderSettings.cameraList[currentPlayerIndex].viewport.Height, 0.3f, 100000f); // Post Draw for Humans if (humans[currentPlayerIndex].IsAlive()) { //Draw the HUD for this human player humans[currentPlayerIndex].HUD.Draw(spriteBatch); } else { //Draw the dead HUD for dead player humans[currentPlayerIndex].deadHUD.Draw(spriteBatch); } // Mark Other Players // -The further away the enemy is, the smaller and fainter the icon // -scale range: 0.25-1.0, alpha range: 50-200 float distance = 0.0f; float distRatio = 0.0f; float totalScale = 0.25f; Vector3 position = new Vector3(); // Draw AI bots foreach (Player bot in bots) { if (bot.IsAlive()) { DrawEnemyTargets(currentPlayerIndex, spriteBatch, ref position, ref distance, ref distRatio, totalScale, bot); } } // Draw Humans foreach (Player player in humans) { if (player.IsAlive() && player != humans[currentPlayerIndex]) { DrawEnemyTargets(currentPlayerIndex, spriteBatch, ref position, ref distance, ref distRatio, totalScale, player); } } } private void DrawEnemyTargets(int currentPlayerIndex, SpriteBatch spriteBatch, ref Vector3 position, ref float distance, ref float distRatio, float totalScale, Player player) { distance = Vector3.Distance(player.mass.currentPosition, humans[currentPlayerIndex].mass.currentPosition); if (distance > Statics.PlayerSettings.ENEMY_MARKER_MIN_DISTANCE) { position = Statics.SystemSettings.graphics.GraphicsDevice.Viewport.Project(player.mass.currentPosition, Statics.RenderSettings.matrixProjection, Statics.RenderSettings.matrixView, Matrix.Identity); if (position.Z < 1) { position.X -= Statics.SystemSettings.graphics.GraphicsDevice.Viewport.X; position.Y -= Statics.SystemSettings.graphics.GraphicsDevice.Viewport.Y; if (position.X >= 0 && position.X < Statics.SystemSettings.graphics.GraphicsDevice.Viewport.Width && position.Y >= 0 && position.Y < Statics.SystemSettings.graphics.GraphicsDevice.Viewport.Height) { distRatio = 1.0f - (distance / Statics.PlayerSettings.ENEMY_MARKER_MAX_DISTANCE); //if negative they are too far away if (distRatio < 0) { distRatio = 0; } spriteBatch.Draw(enemyTargetReticle, new Rectangle((int)(position.X - (enemyTargetReticle.Width * distRatio * totalScale) / 2), (int)(position.Y - (enemyTargetReticle.Height * distRatio * totalScale)), (int)(enemyTargetReticle.Width * distRatio * totalScale), (int)(enemyTargetReticle.Height * distRatio * totalScale)), new Color(255, 255, 255, (byte)(200 * distRatio))); } } } } #endregion } } /* Legacy Code /// <summary> /// Function to reset our list of human players /// </summary> public void DeinitializeHumans() { //be warned.. MUST call Statics.CheckForControllers after this!! foreach (Human human in humans) { human.playerController.playerControllerType = Enums.ControllerType.NONE; human.health = 0; human.manna = 0; } } public void GetDrawObjects() { for (int i = 0; i < humans.Count; i++) { if (humans[i].IsAlive()) { lookupMap.GetDrawObjects(humans[i].mass, drawList[i]); } } } // Test Function to update energy distribution public void UpdateHeatDissipation(ObjectLibrary objectLibrary, float dt) { List<Particle> newParticlesToAddToList = new List<Particle>(); foreach (Particle particle in particles) { particle.mass.UpdatePosition(dt); } // Iterate through dynamic particles for (int i = 0; i < particles.Count; i++) { Particle particle = particles[i]; // List to store the pointers to neighboring particles List<Particle> neighboringParticleList = new List<Particle>(); // Used to calculate the average value of all neighboring particles float averageEnergy = particle.mass.energy; // Get the list of neighboring particle pointers neighboringParticleList = GetSurroundingParticles(particle.mass.currentPosition, objectLibrary); // Calculate their total energy foreach (Particle neigborParticle in neighboringParticleList) { averageEnergy += neigborParticle.mass.energy; } // Find the average averageEnergy /= neighboringParticleList.Count + 1; // If the average value is not equal to zero then we have some heat dissipation to do if (averageEnergy != particle.mass.energy && neighboringParticleList.Count != 0) { // Iterate through neighboring particles foreach (Particle neigborParticle in neighboringParticleList) { // If their value is not equal to the average set it and set the flag if (neigborParticle.mass.energy != averageEnergy) { neigborParticle.mass.SetEnergy(averageEnergy); if (!neigborParticle.mass.isChanging) { neigborParticle.mass.isChanging = true; newParticlesToAddToList.Add(neigborParticle); } } } // Set the starting particle's energy to average value as well particle.mass.SetEnergy(averageEnergy); } else if (particle.mass.energy != 0.0f) { DissipateHeat(particle); } else { // The particle and it's neighbors are in equilibrium so remove it from the list particle.mass.isChanging = false; if (!particle.mass.isMoving) { // Particle needs to be put back into the static list MoveParticle(particles, particles, particle); } else { particles.Remove(particle); } i--; } } foreach (Particle newParticle in newParticlesToAddToList) { if (particles.Contains(newParticle)) { continue; } if (newParticle.mass.isMoving) { CopyParticle(particles, particles, newParticle); } else { MoveParticle(particles, particles, newParticle); } } } public void StateChange(ObjectLibrary objectLibrary, float elementUse, GameObject gameObject) { Particle particle = (Particle)gameObject; gameObject.mass.ChangeEnergy(elementUse / 2.0f); if (gameObject.mass.isChanging) { return; } else if (gameObject.mass.isMoving) { // Particle is in the dynamic list so we need to copy it to the Thermal list switch (particle.particleType) { case Particle.ParticleType.Air: { objectLibrary.particleManager.air.CopyParticle(objectLibrary.particleManager.air.dynamicParticles, objectLibrary.particleManager.air.thermalParticles, particle); break; } case Particle.ParticleType.Water: { objectLibrary.particleManager.water.CopyParticle(objectLibrary.particleManager.water.dynamicParticles, objectLibrary.particleManager.water.thermalParticles, particle); break; } case Particle.ParticleType.Earth: { objectLibrary.particleManager.earth.CopyParticle(objectLibrary.particleManager.earth.dynamicParticles, objectLibrary.particleManager.earth.thermalParticles, particle); break; } } gameObject.mass.isChanging = true; } else { // It's in the static list, so move the particle to the dynamic list switch (particle.particleType) { case Particle.ParticleType.Air: { objectLibrary.particleManager.air.MoveParticle(objectLibrary.particleManager.air.staticParticles, objectLibrary.particleManager.air.thermalParticles, particle); break; } case Particle.ParticleType.Water: { objectLibrary.particleManager.water.MoveParticle(objectLibrary.particleManager.water.staticParticles, objectLibrary.particleManager.water.thermalParticles, particle); break; } case Particle.ParticleType.Earth: { objectLibrary.particleManager.earth.MoveParticle(objectLibrary.particleManager.earth.staticParticles, objectLibrary.particleManager.earth.thermalParticles, particle); break; } } gameObject.mass.isChanging = true; } } public void UpdateLightPosition() { // Light goes 180 degrees back and forth (never below) //if (Math.Abs(lightMoveAngle1) > Math.PI / 2.0f) //{ // LIGHT_MOVE_SPEED1 = -LIGHT_MOVE_SPEED1; //} // Light goes full 360 degrees // Update light source position if (lightMoveAngle1 < 0) { //reset to 2PI lightMoveAngle1 = Math.PI * 2.0f; } else if (lightMoveAngle1 > Math.PI * 2.0f) { //reset to zero lightMoveAngle1 = 0.0f; } // Update the angle of the light lightMoveAngle1 += LIGHT_MOVE_SPEED1; //Calculate the X and Y based on the angle float dx = (float)(lightDistance1 * Math.Sin(lightMoveAngle1)); float dz = (float)(lightDistance1 * Math.Cos(lightMoveAngle1)); lightInfo1.M11 = dx + (Statics.TerrainSettings.collisionMapSize / 2.0f); lightInfo1.M13 = dz +(Statics.TerrainSettings.collisionMapSize / 2.0f); } */