/// <summary> /// Create a Player object from a ship definition. /// </summary> /// <param name="ship">The target ship</param> /// <param name="index">Player index</param> /// <returns>New player object</returns> public static Player cloneShip(GameObject ship, PlayerIndex index) { Player go = new Player(index); go.mass = ship.mass; go.size = ship.size; if (ship.explosion != null) { go.explosion = ship.explosion.clone(); } go.rateL = ship.rateL; go.rateR = ship.rateR; go.dragL = ship.dragL; go.dragR = ship.dragR; go.maxHealth = ship.maxHealth; go.health = ship.maxHealth; go.maxShield = ship.maxShield; go.shield = ship.maxShield; go.shieldIncreaseRate = ship.shieldIncreaseRate; foreach (FBXModel model in ship.models) { go.models.Add(model.clone()); } if (ship.shieldModel != null) { go.shieldModel = ship.shieldModel.clone(); } foreach(MountPoint mount in ship.mounts) { go.mounts.Add(mount.clone()); } foreach (Turret turret in ship.turrets) { go.turrets.Add(turret.clone()); } go.relativeLookAt = new Vector3(ship.relativeLookAt.X, ship.relativeLookAt.Y, ship.relativeLookAt.Z); go.relativeLookFrom = new Vector3(ship.relativeLookFrom.X, ship.relativeLookFrom.Y, ship.relativeLookFrom.Z); go.relationalScale = ship.relationalScale; go.thrusterSFX = ship.thrusterSFX; go.engine_startSFX = ship.engine_startSFX; go.onDeathSound = ship.onDeathSound; return go; }
/// <summary> /// Render a set of objects for a given player. /// </summary> /// <param name="objects"></param> /// <param name="player">Player who is relevant to the rendering being done. Player's camera will be used as the scene /// camera, and player's race status can affect how things are rendered. Leave null if it is not a /// player specific scene.</param> private void renderObjects(List<GameObject> objects, Player player) { Matrix cameraMatrix = player.getCameraLookAtMatrix(); renderObjects(objects, cameraMatrix, player); }
/// <summary> /// Render a set of objects with a given camera matrix. /// </summary> /// <param name="objects"></param> /// <param name="cameraMatrix"></param> /// <param name="player">Player who is relevant to the rendering being done. Leave null if it is not a /// player specific scene.</param> private void renderObjects(List<GameObject> objects, Matrix cameraMatrix, Player player) { Matrix worldMatrix = Matrix.Identity; Matrix objectMatrix; foreach (GameObject gameObject in objects) { objectMatrix = worldMatrix * gameObject.position.matrix(); List<FBXModel> fbxmodels = new List<FBXModel>(gameObject.models); foreach (FBXModel fbxmodel in fbxmodels) { renderFBXModel(gameObject, fbxmodel, cameraMatrix, objectMatrix, player); } } foreach (GameObject gameObject in objects) { objectMatrix = worldMatrix * gameObject.position.matrix(); renderFBXModel(gameObject, gameObject.shieldModel, cameraMatrix, objectMatrix, player); } }
/// <summary> /// Render an object based on an FBX file within a given camera matrix. /// </summary> /// <param name="gameObject">The GameObject the model belongs to.</param> /// <param name="fbxmodel">The FBX model to draw.</param> /// <param name="cameraMatrix">The camera matrix.</param> /// <param name="objectMatrix">The object matrix.</param> /// <param name="player">What player's view is being rendered.</param> private void renderFBXModel(GameObject gameObject, FBXModel fbxmodel, Matrix cameraMatrix, Matrix objectMatrix, Player player) { Matrix modelMatrix; if (fbxmodel == null || !fbxmodel.visible) { return; } // TODO: We need to get an appropriate colored fog if we really want to not fog the skybox bool enableFog = false; // || !(gameObject is Skybox); if (gameObject is Checkpoint) { int currentLocation = Engine.GetInstance().race.status(player, true).checkpoint; int checkpointPosition = ((Checkpoint)gameObject).racePosition; if (checkpointPosition > currentLocation) { // TODO: change differentiation from visible/invisible to differences in how the checkpoints are rendered (color? brightness?) fbxmodel.visible = true; } else { fbxmodel.visible = false; } } modelMatrix = Matrix.CreateScale(fbxmodel.scale) * objectMatrix * fbxmodel.offset.matrix(); Model model = fbxmodel.model; // Copy any parent transforms. Matrix[] transforms = new Matrix[model.Bones.Count]; model.CopyAbsoluteBoneTransformsTo(transforms); // Draw the model. A model can have multiple meshes, so loop. foreach (ModelMesh mesh in model.Meshes) { bool meshbloom = false; foreach (BasicEffect mesheffect in mesh.Effects) { if (mesheffect.EmissiveColor != Vector3.Zero) { meshbloom = true; } } // This is where the mesh orientation is set, as well as our camera and projection. foreach (BasicEffect mesheffect in mesh.Effects) { mesheffect.PreferPerPixelLighting = Properties.Settings.Default.PerPixelLighting; mesheffect.FogEnabled = enableFog; mesheffect.FogStart = viewingDistance / 2; mesheffect.FogEnd = viewingDistance * 1.25f; mesheffect.FogColor = new Vector3(0, 0, 0); mesheffect.World = transforms[mesh.ParentBone.Index] * modelMatrix; //effect.View = Matrix.CreateLookAt(cameraPosition, Vector3.Zero, Vector3.Up); mesheffect.View = cameraMatrix; mesheffect.Projection = Matrix.CreatePerspectiveFieldOfView(MathHelper.ToRadians(viewingAngle), GammaDraconis.GetInstance().GraphicsDevice.Viewport.AspectRatio, 10f, viewingDistance); if (renderBloom) { if (meshbloom) { applyLights(mesheffect, fbxmodel.lighted); } else { mesheffect.LightingEnabled = true; mesheffect.DirectionalLight0.Enabled = false; mesheffect.DirectionalLight1.Enabled = false; mesheffect.DirectionalLight2.Enabled = false; mesheffect.AmbientLightColor = Vector3.Zero; } } else { applyLights(mesheffect, fbxmodel.lighted); } } mesh.Draw(); } }
/// <summary> /// Return a list of GameObjects that are within range and /// viewing arc of the given vantage point coordinates. /// </summary> /// <param name="vantage">Vantage point Coords to render from</param> /// <param name="player">player relevant to the scene</param> /// <returns>List of GameObjects to render</returns> public List<GameObject> visible(Coords vantage, Player player) { Room roomIn = null; foreach (Room room in rooms) { if (room.area.Contains(vantage.pos()) != ContainmentType.Disjoint) { roomIn = room; break; } } Dictionary<int, List<GameObject>> visibleObjects = new Dictionary<int, List<GameObject>>(); if (roomIn == null || roomIn.canSeeOutside) { updateOctTreeObjects(); float aspRatio = GammaDraconis.renderer.aspectRatio; float viewAngle = GammaDraconis.renderer.viewingAngle; float viewDist = GammaDraconis.renderer.viewingDistance; Matrix view = Matrix.CreateLookAt(vantage.pos() - Matrix.CreateFromQuaternion(vantage.R).Forward, vantage.pos(), Matrix.CreateFromQuaternion(vantage.R).Up); BoundingFrustum viewFrustum = new BoundingFrustum(view * Matrix.CreatePerspectiveFieldOfView(MathHelper.ToRadians(viewAngle), aspRatio, 0.1f, viewDist)); Dictionary<int, List<GameObject>> optimizedObjects = new Dictionary<int, List<GameObject>>(objects);//sortOctTree(out visibleObjects, viewFrustum); foreach (int tempKey in optimizedObjects.Keys) { if (!visibleObjects.ContainsKey(tempKey)) visibleObjects.Add(tempKey, new List<GameObject>()); List<GameObject> tempKeyObjects = optimizedObjects[tempKey]; foreach (GameObject gameobject in tempKeyObjects) { // Take care of some quick cases before doing any math. if ((tempKey & GO_TYPE.SKYBOX) == GO_TYPE.SKYBOX) { visibleObjects[GO_TYPE.SKYBOX].Add(gameobject); gameobject.position.T = Matrix.CreateTranslation(vantage.pos()); } else { if (viewFrustum.Contains(new BoundingSphere(gameobject.position.pos(), gameobject.size)) != ContainmentType.Disjoint) { visibleObjects[tempKey].Add(gameobject); } } } } } else // roomIn != null { foreach (int tempKey in objects.Keys) { if (!visibleObjects.ContainsKey(tempKey)) visibleObjects.Add(tempKey, new List<GameObject>()); foreach (GameObject gameobject in objects[tempKey]) { if ((tempKey & GO_TYPE.SKYBOX) == GO_TYPE.SKYBOX) { visibleObjects[GO_TYPE.SKYBOX].Add(gameobject); gameobject.position.T = Matrix.CreateTranslation(vantage.pos()); } else { bool visible = false; if (roomIn.area.Contains(gameobject.position.pos()) != ContainmentType.Disjoint) { visible = true; } else { foreach (Room room in roomIn.visibleRooms) { if (room.area.Contains(gameobject.position.pos()) != ContainmentType.Disjoint) { visible = true; break; } } } if (visible) { if ((tempKey & GO_TYPE.SCENERY) == GO_TYPE.SCENERY) gameobject.position.R = Quaternion.CreateFromRotationMatrix(Matrix.CreateBillboard(vantage.pos(), gameobject.position.pos(), Vector3.One, Vector3.Forward)); visibleObjects[tempKey].Add(gameobject); } } } } } // Player specific visibility logic if (visibleObjects.ContainsKey(GO_TYPE.CHECKPOINT)) { foreach (GameObject gameObject in visibleObjects[GO_TYPE.CHECKPOINT]) { RaceStatus status = Engine.GetInstance().race.status(player, true); int lap = status.lap; int currentLocation = status.checkpoint; int checkpointPosition = ((Checkpoint)gameObject).racePosition; if (checkpointPosition > currentLocation) { // TODO: change differentiation from visible/invisible to differences in how the checkpoints are rendered (color? brightness?) gameObject.models[0].visible = true; gameObject.models[1].visible = false; } else { gameObject.models[0].visible = false; gameObject.models[1].visible = true; } } } if (visibleObjects.ContainsKey(GO_TYPE.DIRECTIONAL_ARROW)) { List<GameObject> removeTheseArrows = new List<GameObject>(); foreach (GameObject gameObject in visibleObjects[GO_TYPE.DIRECTIONAL_ARROW]) { if(!player.arrow.Equals(gameObject)){ removeTheseArrows.Add(gameObject); } } foreach (GameObject gameObject in removeTheseArrows) { visibleObjects[GO_TYPE.DIRECTIONAL_ARROW].Remove(gameObject); } } List<GameObject> shownObjects = sortObjects(visibleObjects); if (player != null) { shownObjects.AddRange(player.dust); } return shownObjects; }
/// <summary> /// Return a list of GameObjects that are within range and /// viewing arc of the given vantage point coordinates. /// </summary> /// <param name="player">player relevant to the scene</param> /// <returns>List of GameObjects to render</returns> public List<GameObject> visible(Player player) { return visible(player.getCamera(), player); }