diff --git a/FotosGameplay/Gameplay.png b/FotosGameplay/Gameplay.png new file mode 100644 index 000000000..03595bfba --- /dev/null +++ b/FotosGameplay/Gameplay.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:d2377a436eb61763ffed03edd15775b6262934ca47fbcb8ad25f5d4ae232c09a +size 1174163 diff --git a/FotosGameplay/Menu.png b/FotosGameplay/Menu.png new file mode 100644 index 000000000..fbd9fb376 --- /dev/null +++ b/FotosGameplay/Menu.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:cafb8759c336f1753c87a6f885585cf9fea7eb8db0d1836cc9934bdd39bd580a +size 263885 diff --git a/FotosTGCitos/Lucas Gelabert.png b/FotosTGCitos/Lucas Gelabert.png new file mode 100644 index 000000000..4379b64e1 --- /dev/null +++ b/FotosTGCitos/Lucas Gelabert.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:b30094d366f763a12c445c035ffd10e010adee64f887644ea03edb3a57c6c199 +size 345633 diff --git a/FotosTGCitos/Santiago Saucedo.png b/FotosTGCitos/Santiago Saucedo.png new file mode 100644 index 000000000..ca6b3dc7b --- /dev/null +++ b/FotosTGCitos/Santiago Saucedo.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:7eb56711c37f0bc819a8ce63d4e60a3a9b772dfdbdd55d659fce8ad1c5ed1f65 +size 209461 diff --git a/FotosTGCitos/Simon Cutrera.png b/FotosTGCitos/Simon Cutrera.png new file mode 100644 index 000000000..4a0955970 --- /dev/null +++ b/FotosTGCitos/Simon Cutrera.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:a95830342bfe853c0a514716c3d5f4058d7882e04ea4db6b6e510ac07275e9c8 +size 280335 diff --git a/FotosTGCitos/Tomas Zubizarreta.png b/FotosTGCitos/Tomas Zubizarreta.png new file mode 100644 index 000000000..0d4c77afb --- /dev/null +++ b/FotosTGCitos/Tomas Zubizarreta.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:4b6a91ad94bcfaf446a69bab2fe487d59264017517488dd69f95573a29d8abcc +size 263625 diff --git a/README.md b/README.md index e0c207bd0..6f5b4e68d 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -# TGC - MonoGame - TP +# TGC - MonoGame - Thundering Tanks [![.NET](https://github.com/tgc-utn/tgc-monogame-tp/actions/workflows/dotnet.yml/badge.svg)](https://github.com/tgc-utn/tgc-monogame-tp/actions/workflows/dotnet.yml) [![Codacy Badge](https://app.codacy.com/project/badge/Grade/63382c4441444632b06d83dcc6dab106)](https://app.codacy.com/gh/tgc-utn/tgc-monogame-tp/dashboard?utm_source=gh&utm_medium=referral&utm_content=&utm_campaign=Badge_grade) @@ -6,32 +6,33 @@ [#BuiltWithMonoGame](http://www.monogame.net) and [.NET Core](https://dotnet.microsoft.com) -## Descripción +## Descripcion +Juego de batalla de tanques creado por estudiantes de la carrera de ingenieria en sistemas de la UTN de buenos aires para la materia Tecnicas De Graficos Por Computadora utilizando el FrameWork Monogame. -Proyecto plantilla para los trabajos prácticos de la asignatura electiva [Técnicas de Gráficos por Computadora](http://tgc-utn.github.io/) (TGC) en la carrera de Ingeniería en Sistemas de Información. Universidad Tecnológica Nacional, Facultad Regional Buenos Aires (UTN-FRBA). - -## Configuración del entorno de desarrollo - -Los pasos a seguir según su sistema operativo se pueden leer en el siguiente documento [install.md](https://github.com/tgc-utn/tgc-monogame-samples/blob/master/docs/install/install.md). - -Afuera del mundo Windows, vas a necesitar la ayudar de [Wine](https://www.winehq.org) para los shaders, por lo menos por [ahora](https://github.com/MonoGame/MonoGame/issues/2167). - -Los recursos usados se almacenan utilizando [Git LFS](https://git-lfs.github.com), con lo cual antes de clonar el repositorio les conviene tenerlo instalado así es automático el pull o si ya lo tienen pueden hacer `git lfs pull`. +## Controles +Tecla | Accion +----- | ----- +W | Movimiento hacia adelante +A | Rotacion izquierda +S | Movimiento hacia atras +D | Rotacion derecha +C | Debug mode +G | God mode +Click Izquierdo | Disparo de cañon ## Integrantes TGC, Tgcito | Apellido, Nombre ------------ | ------------- -| | | +| ![Lucas Gelabert](/FotosTGCitos/Lucas%20Gelabert.png) | Lucas Gelabert | +| ![Santiago Saucedo](/FotosTGCitos/Santiago%20Saucedo.png) | Santiago Saucedo | +| ![Simon Cutrera](/FotosTGCitos/Simon%20Cutrera.png) | Simon Cutrera | +| ![Tomas Zubizarreta](/FotosTGCitos/Tomas%20Zubizarreta.png) | Tomas Zubizarreta | ## Capturas -![screenshot1](https://github.com/tgc-utn/tgc-monogame-tp/blob/master/TGC.MonoGame.TP/Icon.bmp) -![screenshot2](https://github.com/tgc-utn/tgc-monogame-tp/blob/master/TGC.MonoGame.TP/Icon.bmp) -![screenshot3](https://github.com/tgc-utn/tgc-monogame-tp/blob/master/TGC.MonoGame.TP/Icon.bmp) -![screenshot4](https://github.com/tgc-utn/tgc-monogame-tp/blob/master/TGC.MonoGame.TP/Icon.bmp) -![screenshot5](https://github.com/tgc-utn/tgc-monogame-tp/blob/master/TGC.MonoGame.TP/Icon.bmp) +![Menu](/FotosGameplay/Menu.png) -## Game Play +![Gameplay](/FotosGameplay/Gameplay.png) -[![Watch the video](https://img.youtube.com/vi/pgEwUC0jvH4/0.jpg)](https://www.youtube.com/playlist?list=PLRM4L32DjvnazuMl8wZlbpEYL5Qh63ulG) +## Game Play diff --git a/TGC.MonoGame.TP/Animations/DataTypes/AnimationBone.cs b/TGC.MonoGame.TP/Animations/DataTypes/AnimationBone.cs new file mode 100644 index 000000000..7eb02ccdf --- /dev/null +++ b/TGC.MonoGame.TP/Animations/DataTypes/AnimationBone.cs @@ -0,0 +1,21 @@ +using System.Collections.Generic; +using ThunderingTanks.Animation; + +namespace ThunderingTanks.Animation.DataTypes; + +/// +/// Keyframes are grouped per bone for an animation clip. +/// +public class AnimationBone +{ + /// + /// The keyframes for this bone. + /// + public List Keyframes { get; set; } = new(); + + /// + /// The bone name for these keyframes. + /// Each bone has a name so we can associate it with a runtime model. + /// + public string Name { get; set; } = string.Empty; +} \ No newline at end of file diff --git a/TGC.MonoGame.TP/Animations/DataTypes/AnimationClip.cs b/TGC.MonoGame.TP/Animations/DataTypes/AnimationClip.cs new file mode 100644 index 000000000..67cce7dee --- /dev/null +++ b/TGC.MonoGame.TP/Animations/DataTypes/AnimationClip.cs @@ -0,0 +1,25 @@ +using System.Collections.Generic; +using ThunderingTanks.Animation; + +namespace ThunderingTanks.Animation.DataTypes; + +/// +/// An animation clip is a set of keyframes with associated bones. +/// +public class AnimationClip +{ + /// + /// The bones for this animation clip with their keyframes. + /// + public List Bones { get; set; } = new(); + + /// + /// Duration of the animation clip. + /// + public double Duration { get; set; } + + /// + /// Name of the animation clip. + /// + public string Name { get; set; } +} \ No newline at end of file diff --git a/TGC.MonoGame.TP/Animations/DataTypes/Keyframe.cs b/TGC.MonoGame.TP/Animations/DataTypes/Keyframe.cs new file mode 100644 index 000000000..183512fbf --- /dev/null +++ b/TGC.MonoGame.TP/Animations/DataTypes/Keyframe.cs @@ -0,0 +1,40 @@ +using Microsoft.Xna.Framework; +using ThunderingTanks.Animation; + +namespace ThunderingTanks.Animation.DataTypes; + +/// +/// An Keyframe is a rotation and Translation for a moment in time. +/// It would be easy to extend this to include scaling as well. +/// +public class Keyframe +{ + /// + /// The rotation for the bone. + /// + public Quaternion Rotation { get; set; } + + /// + /// The keyframe time. + /// + public double Time { get; set; } + + /// + /// The Translation for the bone. + /// + public Vector3 Translation { get; set; } + + public Matrix Transform + { + get => Matrix.CreateFromQuaternion(Rotation) * Matrix.CreateTranslation(Translation); + set + { + var transform = value; + transform.Right = Vector3.Normalize(transform.Right); + transform.Up = Vector3.Normalize(transform.Up); + transform.Backward = Vector3.Normalize(transform.Backward); + Rotation = Quaternion.CreateFromRotationMatrix(transform); + Translation = transform.Translation; + } + } +} \ No newline at end of file diff --git a/TGC.MonoGame.TP/Animations/DataTypes/ModelExtra.cs b/TGC.MonoGame.TP/Animations/DataTypes/ModelExtra.cs new file mode 100644 index 000000000..99f36aca4 --- /dev/null +++ b/TGC.MonoGame.TP/Animations/DataTypes/ModelExtra.cs @@ -0,0 +1,19 @@ +using System.Collections.Generic; + +namespace ThunderingTanks.Animation.DataTypes; + +/// +/// Class that contains additional information attached to the model and shared with the runtime. +/// +public class ModelExtra +{ + /// + /// Animation clips associated with this model. + /// + public List Clips { get; set; } = new(); + + /// + /// The bone indices for the skeleton associated with any skinned model. + /// + public List Skeleton { get; set; } = new(); +} \ No newline at end of file diff --git a/TGC.MonoGame.TP/Animations/Models/AnimatedModel.cs b/TGC.MonoGame.TP/Animations/Models/AnimatedModel.cs new file mode 100644 index 000000000..5eb681e3c --- /dev/null +++ b/TGC.MonoGame.TP/Animations/Models/AnimatedModel.cs @@ -0,0 +1,162 @@ +using System.Collections.Generic; +using System.Linq; +using Microsoft.Xna.Framework; +using Microsoft.Xna.Framework.Content; +using Microsoft.Xna.Framework.Graphics; +using ThunderingTanks.Animation.DataTypes; + +namespace ThunderingTanks.Animation.Models; + +/// +/// An enclosure for an XNA Model that we will use that includes support for Bones, animation, and some manipulations. +/// +public class AnimatedModel +{ + /// + /// The Model asset name. + /// + private readonly string _assetName; + + /// + /// The underlying Bones for the Model. + /// + private readonly List _bones = new(); + + /// + /// The actual underlying XNA Model. + /// + private Model _model; + + /// + /// Extra data associated with the XNA Model. + /// + private ModelExtra _modelExtra; + + /// + /// An associated animation clip Player. + /// + private AnimationPlayer _player; + + /// + /// The Model animation clips. + /// + public List Clips => _modelExtra.Clips; + + /// + /// Creates the Model from an XNA Model. + /// + /// The name of the asset for this Model. + public AnimatedModel(string assetName) + { + _assetName = assetName; + } + + /// + /// Play an animation clip. + /// + /// The clip to play. + /// The Player that will play this clip. + public AnimationPlayer PlayClip(AnimationClip clip) + { + // Create a clip Player and assign it to this Model. + _player = new AnimationPlayer(clip, this); + return _player; + } + + /// + /// Update animation for the Model. + /// + public void Update(GameTime gameTime) + { + _player.Update(gameTime); + } + + /// + /// Draw the Model. + /// + /// A world matrix to place the Model. + /// The view matrix, normally from the camera. + /// The projection matrix, normally from the application. + public void Draw(Matrix world, Matrix view, Matrix projection) + { + // Compute all of the bone absolute transforms. + var boneTransforms = new Matrix[_bones.Count]; + + for (var i = 0; i < _bones.Count; i++) + { + var bone = _bones[i]; + bone.ComputeAbsoluteTransform(); + + boneTransforms[i] = bone.AbsoluteTransform; + } + + // Determine the skin transforms from the skeleton. + var skeleton = new Matrix[_modelExtra.Skeleton.Count]; + for (var s = 0; s < _modelExtra.Skeleton.Count; s++) + { + var bone = _bones[_modelExtra.Skeleton[s]]; + skeleton[s] = bone.SkinTransform * bone.AbsoluteTransform; + } + + // Draw the Model. + foreach (var modelMesh in _model.Meshes) + { + foreach (var effect in modelMesh.Effects) + { + var skinnedEffect = effect as SkinnedEffect; + skinnedEffect.World = boneTransforms[modelMesh.ParentBone.Index] * world; + skinnedEffect.View = view; + skinnedEffect.Projection = projection; + skinnedEffect.EnableDefaultLighting(); + skinnedEffect.PreferPerPixelLighting = true; + skinnedEffect.SetBoneTransforms(skeleton); + } + + modelMesh.Draw(); + } + } + + /// + /// Load the Model asset from content. + /// + public void LoadContent(ContentManager content) + { + _model = content.Load(_assetName); + _modelExtra = _model.Tag as ModelExtra; + + ObtainBones(); + } + + /// + /// Get the Bones from the Model and create a bone class object for each bone. We use our bone class to do the real + /// animated bone work. + /// + private void ObtainBones() + { + _bones.Clear(); + foreach (var bone in _model.Bones) + { + // Create the bone object and add to the hierarchy. + var newBone = new Bone(bone.Name, bone.Transform, bone.Parent != null ? _bones[bone.Parent.Index] : null); + + // Add to the Bones for this Model. + _bones.Add(newBone); + } + } + + /// + /// Find a bone in this Model by name. + /// + public Bone FindBone(string name) + { + foreach (var bone in _bones) + { + if (bone.Name == name) + { + return bone; + } + } + + return null; + } +} \ No newline at end of file diff --git a/TGC.MonoGame.TP/Animations/Models/AnimationPlayer.cs b/TGC.MonoGame.TP/Animations/Models/AnimationPlayer.cs new file mode 100644 index 000000000..396f78d63 --- /dev/null +++ b/TGC.MonoGame.TP/Animations/Models/AnimationPlayer.cs @@ -0,0 +1,103 @@ +using Microsoft.Xna.Framework; +using ThunderingTanks.Animation.DataTypes; + +namespace ThunderingTanks.Animation.Models; + +/// +/// Animation Clip player. +/// It maps an animation Clip onto a Model. +/// +public class AnimationPlayer +{ + /// + /// We maintain a BoneInfo class for each bone. + /// This class does most of the work in playing the animation. + /// + private readonly BoneInfo[] _boneInfo; + + /// + /// The Clip we are playing. + /// + private readonly AnimationClip _clip; + + /// + /// Current position in time in the clip. + /// + private float _position; + + /// + /// Constructor for the animation player. + /// It makes the association between a Clip and a Model and sets up for playing. + /// + public AnimationPlayer(AnimationClip clip, AnimatedModel model) + { + _clip = clip; + + // Create the bone information classes. + var boneCount = clip.Bones.Count; + _boneInfo = new BoneInfo[boneCount]; + + for (var b = 0; b < _boneInfo.Length; b++) + { + // Create it. + _boneInfo[b] = new BoneInfo(clip.Bones[b]); + + // Assign it to a Model bone. + _boneInfo[b].SetModel(model); + } + + Rewind(); + } + + /// + /// The Looping option. + /// Set to true if you want the animation to loop back at the end. + /// + public bool Looping { get; set; } + + /// + /// Current Position in time in the Clip. + /// + private float Position + { + get => _position; + set + { + if (value > Duration) + { + value = Duration; + } + + _position = value; + foreach (var bone in _boneInfo) + { + bone.SetPosition(_position); + } + } + } + + /// + /// The Clip duration. + /// + public float Duration => (float)_clip.Duration; + + /// + /// Reset back to time zero. + /// + public void Rewind() + { + Position = 0; + } + + /// + /// Update the Clip Position. + /// + public void Update(GameTime gameTime) + { + Position += (float)gameTime.ElapsedGameTime.TotalSeconds; + if (Looping && Position >= Duration) + { + Position = 0; + } + } +} \ No newline at end of file diff --git a/TGC.MonoGame.TP/Animations/Models/Bone.cs b/TGC.MonoGame.TP/Animations/Models/Bone.cs new file mode 100644 index 000000000..a1089687b --- /dev/null +++ b/TGC.MonoGame.TP/Animations/Models/Bone.cs @@ -0,0 +1,133 @@ +using System.Collections.Generic; +using Microsoft.Xna.Framework; +using ThunderingTanks.Animation.DataTypes; + + +namespace ThunderingTanks.Animation.Models; + +/// +/// Bones in this model are represented by this class, which allows a bone to have more detail associate with it. +/// This class allows you to manipulate the local coordinate system for objects by changing the scaling, Translation, +/// and Rotation. +/// These are independent of the bind transformation originally supplied for the model. +/// So, the actual transformation for a bone is the product of the: +/// * Scaling. +/// * Bind scaling (scaling removed from the bind transform). +/// * Rotation. +/// * Translation. +/// * Bind Transformation. +/// * Parent Absolute Transformation. +/// +public class Bone +{ + /// + /// The bind scaling component extracted from the bind transform. + /// + private readonly Vector3 _bindScale; + + /// + /// The bind transform is the transform for this bone as loaded from the original model. It's the base pose. + /// I do remove any scaling, though. + /// + private readonly Matrix _bindTransform; + + /// + /// The Children of this bone. + /// + private readonly List _children = new(); + + /// + /// The Parent bone or null for the root bone. + /// + private readonly Bone _parent; + + /// + /// Any scaling applied to the bone. + /// + private readonly Vector3 _scale = Vector3.One; + + /// + /// Any Rotation applied to the bone. + /// + private Quaternion _rotation = Quaternion.Identity; + + /// + /// Any Translation applied to the bone. + /// + private Vector3 _translation = Vector3.Zero; + + /// + /// Constructor for a bone object. + /// + /// The name of the bone. + /// The initial bind transform for the bone. + /// A Parent for this bone. + public Bone(string name, Matrix bindTransform, Bone parent) + { + Name = name; + _parent = parent; + parent?._children.Add(this); + + // In this example, scaling in animation is not supported. The bind scaling is separated from the bind transform and saved. + _bindScale = new Vector3(bindTransform.Right.Length(), bindTransform.Up.Length(), + bindTransform.Backward.Length()); + + bindTransform.Right /= _bindScale.X; + bindTransform.Up /= _bindScale.Y; + bindTransform.Backward /= _bindScale.Y; + _bindTransform = bindTransform; + + // Set the skinning bind transform. + // That is the inverse of the absolute transform in the bind pose. + ComputeAbsoluteTransform(); + SkinTransform = Matrix.Invert(AbsoluteTransform); + } + + /// + /// The bone absolute transform. + /// + public Matrix AbsoluteTransform { get; set; } = Matrix.Identity; + + /// + /// The bone name. + /// + public string Name { get; set; } + + /// + /// Inverse of absolute bind transform for skinning. + /// + public Matrix SkinTransform { get; set; } + + /// + /// Compute the absolute transformation for this bone. + /// + public void ComputeAbsoluteTransform() + { + var transform = Matrix.CreateScale(_scale * _bindScale) * Matrix.CreateFromQuaternion(_rotation) * + Matrix.CreateTranslation(_translation) * _bindTransform; + + if (_parent != null) + // This bone has a Parent bone. + { + AbsoluteTransform = transform * _parent.AbsoluteTransform; + } + else + // The root bone. + { + AbsoluteTransform = transform; + } + } + + /// + /// This sets the Rotation and Translation such that the Rotation times the Translation times the bind after set equals + /// this matrix. This is used to set animation values. + /// + /// A matrix include Translation and Rotation + public void SetCompleteTransform(Matrix m) + { + var setTo = m * Matrix.Invert(_bindTransform); + + _translation = setTo.Translation; + _rotation = Quaternion.CreateFromRotationMatrix(setTo); + } +} \ No newline at end of file diff --git a/TGC.MonoGame.TP/Animations/Models/BoneInfo.cs b/TGC.MonoGame.TP/Animations/Models/BoneInfo.cs new file mode 100644 index 000000000..c3fe5cd47 --- /dev/null +++ b/TGC.MonoGame.TP/Animations/Models/BoneInfo.cs @@ -0,0 +1,147 @@ +using Microsoft.Xna.Framework; +using ThunderingTanks.Animation.DataTypes; + +namespace ThunderingTanks.Animation.Models; + +/// +/// Information about a bone we are animating. +/// This class connects a bone in the clip to a bone in the model. +/// +public class BoneInfo +{ + /// + /// Bone in a model that this keyframe bone is assigned to. + /// + private Bone _assignedBone; + + /// + /// The current keyframe. Our position is a time such that the we are greater than or equal to this keyframe's time and + /// less than the next keyframes time. + /// + private int _currentKeyframe; + + /// + /// Current animation Rotation. + /// + private Quaternion _rotation; + + /// + /// Constructor. + /// + public BoneInfo(AnimationBone animationBone) + { + ClipAnimationBone = animationBone; + SetKeyframes(); + SetPosition(0); + } + + /// + /// We are at a location between KeyframeFrom and KeyframeTo such that KeyframeFrom time is less than or equal to the + /// current position. + /// + public Keyframe KeyframeFrom { get; set; } + + /// + /// Second keyframe value. + /// + public Keyframe KeyframeTo { get; set; } + + /// + /// Current animation Translation. + /// + public Vector3 Translation { get; set; } + + /// + /// We are not Valid until the Rotation and Translation are set. + /// If there are no keyframes, we will never be Valid. + /// + public bool Valid { get; set; } + + /// + /// The bone in the actual animation clip. + /// + public AnimationBone ClipAnimationBone { get; } + + /// + /// Set the bone based on the supplied position value. + /// + public void SetPosition(float position) + { + var keyframes = ClipAnimationBone.Keyframes; + if (keyframes.Count == 0) + { + return; + } + + // If our current position is less that the first keyframe we move the position backward until we get to the right keyframe. + while (position < KeyframeFrom.Time && _currentKeyframe > 0) + { + // We need to move backwards in time. + _currentKeyframe--; + SetKeyframes(); + } + + // If our current position is greater than the second keyframe we move the position forward until we get to the right keyframe. + while (position >= KeyframeTo.Time && _currentKeyframe < ClipAnimationBone.Keyframes.Count - 2) + { + // We need to move forwards in time. + _currentKeyframe++; + SetKeyframes(); + } + + if (KeyframeFrom == KeyframeTo) + { + // Keyframes are equal. + _rotation = KeyframeFrom.Rotation; + Translation = KeyframeFrom.Translation; + } + else + { + // Interpolate between keyframes. + var t = (float)((position - KeyframeFrom.Time) / (KeyframeTo.Time - KeyframeFrom.Time)); + _rotation = Quaternion.Slerp(KeyframeFrom.Rotation, KeyframeTo.Rotation, t); + Translation = Vector3.Lerp(KeyframeFrom.Translation, KeyframeTo.Translation, t); + } + + Valid = true; + if (_assignedBone == null) + { + return; + } + + // Send to the model. + // Make it a matrix first. + var m = Matrix.CreateFromQuaternion(_rotation); + m.Translation = Translation; + _assignedBone.SetCompleteTransform(m); + } + + /// + /// Set the keyframes to a Valid value relative to the current keyframe. + /// + private void SetKeyframes() + { + if (ClipAnimationBone.Keyframes.Count > 0) + { + KeyframeFrom = ClipAnimationBone.Keyframes[_currentKeyframe]; + KeyframeTo = _currentKeyframe == ClipAnimationBone.Keyframes.Count - 1 + ? KeyframeFrom + : ClipAnimationBone.Keyframes[_currentKeyframe + 1]; + } + else + { + // If there are no keyframes, set both to null. + KeyframeFrom = null; + KeyframeTo = null; + } + } + + /// + /// Assign this bone to the correct bone in the model. + /// + public void SetModel(AnimatedModel model) + { + // Find this bone. + _assignedBone = model.FindBone(ClipAnimationBone.Name); + } +} \ No newline at end of file diff --git a/TGC.MonoGame.TP/Animations/PipelineExtension/AnimationProcessor.cs b/TGC.MonoGame.TP/Animations/PipelineExtension/AnimationProcessor.cs new file mode 100644 index 000000000..27dcb232f --- /dev/null +++ b/TGC.MonoGame.TP/Animations/PipelineExtension/AnimationProcessor.cs @@ -0,0 +1,495 @@ +using System.Collections.Generic; +using Microsoft.Xna.Framework; +using Microsoft.Xna.Framework.Content.Pipeline; +using Microsoft.Xna.Framework.Content.Pipeline.Graphics; +using Microsoft.Xna.Framework.Content.Pipeline.Processors; +using ThunderingTanks.Animation.DataTypes; + +namespace ThunderingTanks.Animation.PipelineExtensions; + +/// +/// This class extends the standard ModelProcessor to include code that extracts a skeleton, pulls any animations, and +/// does any necessary prep work to support animation and skinning. +/// +[ContentProcessor(DisplayName = "Animation Processor")] +public class AnimationProcessor : ModelProcessor +{ + private const float TinyLength = 1e-8f; + private const float TinyCosAngle = 0.9999999f; + + /// + /// Bones lookup table, converts bone names to indices. + /// + private readonly Dictionary _bones = new(); + + /// + /// A dictionary so we can keep track of the clips by name. + /// + private readonly Dictionary _clips = new(); + + /// + /// Extra content to associated with the model. This is where we put the stuff that is unique to this project. + /// + private readonly ModelExtra _modelExtra = new(); + + /// + /// A lookup dictionary that remembers when we changes a material to skinned material. + /// + private readonly Dictionary _toSkinnedMaterial = new(); + + /// + /// This will keep track of all of the bone transforms for a base pose. + /// + private Matrix[] _boneTransforms; + + /// + /// The model we are reading. + /// + private ModelContent _model; + + /// + /// The function to process a model from original content into model content for export. + /// + public override ModelContent Process(NodeContent input, ContentProcessorContext context) + { + // Skeleton Support. + // Process the skeleton for skinned character animation. + ProcessSkeleton(input); + + // Skinned Support. + SwapSkinnedMaterial(input); + + // Base Model process. + _model = base.Process(input, context); + + // Animation Support. + ProcessAnimations(_model, input); + + // Add the extra content to the model. + _model.Tag = _modelExtra; + + return _model; + } + + /// + /// Process the skeleton in support of skeletal animation. + /// + private void ProcessSkeleton(NodeContent input) + { + // Find the skeleton. + var skeleton = MeshHelper.FindSkeleton(input); + + if (skeleton == null) + { + return; + } + + // We don't want to have to worry about different parts of the model being in different local coordinate systems, so let's just bake everything. + FlattenTransforms(input, skeleton); + + // 3D Studio Max includes helper bones that end with "Nub" These are not part of the skinning system and can be discarded. TrimSkeleton removes them from the geometry. + TrimSkeleton(skeleton); + + // Convert the hierarchy of nodes and bones into a list. + var nodes = FlattenHierarchy(input); + var bones = MeshHelper.FlattenSkeleton(skeleton); + + // Create a dictionary to convert a node to an index into the array of nodes. + var nodeToIndex = new Dictionary(); + for (var i = 0; i < nodes.Count; i++) + { + nodeToIndex[nodes[i]] = i; + } + + // Now create the array that maps the bones to the nodes. + foreach (var bone in bones) + { + _modelExtra.Skeleton.Add(nodeToIndex[bone]); + } + } + + /// + /// Convert a tree of nodes into a list of nodes in topological order. + /// + /// The root of the hierarchy. + private List FlattenHierarchy(NodeContent item) + { + var nodes = new List(); + nodes.Add(item); + + foreach (var child in item.Children) + { + FlattenHierarchy(nodes, child); + } + + return nodes; + } + + private void FlattenHierarchy(ICollection nodes, NodeContent item) + { + nodes.Add(item); + + foreach (var child in item.Children) + { + FlattenHierarchy(nodes, child); + } + } + + /// + /// Bakes unwanted transforms into the model geometry, so everything ends up in the same coordinate system. + /// + private void FlattenTransforms(NodeContent node, BoneContent skeleton) + { + foreach (var child in node.Children) + { + // Don't process the skeleton, because that is special. + if (child == skeleton) + { + continue; + } + + // This is important: Don't bake in the transforms except for geometry that is part of a skinned mesh. + if (IsSkinned(child)) + { + FlattenAllTransforms(child); + } + } + } + + /// + /// Recursively flatten all transforms from this node down. + /// + private void FlattenAllTransforms(NodeContent node) + { + // Bake the local transform into the actual geometry. + MeshHelper.TransformScene(node, node.Transform); + + // Having baked it, we can now set the local coordinate system back to identity. + node.Transform = Matrix.Identity; + + foreach (var child in node.Children) + { + FlattenAllTransforms(child); + } + } + + /// + /// 3D Studio Max includes an extra help bone at the end of each IK chain that doesn't effect the skinning system and + /// is redundant as far as any game is concerned. This function looks for children who's name ends with "Nub" and + /// removes them from the hierarchy. + /// + /// Root of the skeleton tree. + private void TrimSkeleton(NodeContent skeleton) + { + var toDelete = new List(); + + foreach (var child in skeleton.Children) + { + if (child.Name.EndsWith("Nub") || child.Name.EndsWith("Footsteps")) + { + toDelete.Add(child); + } + else + { + TrimSkeleton(child); + } + } + + foreach (var child in toDelete) + { + skeleton.Children.Remove(child); + } + } + + /// + /// Determine if a node is a skinned node, meaning it has bone weights associated with it. + /// + private bool IsSkinned(NodeContent node) + { + // It has to be a MeshContent node. + if (node is MeshContent mesh) + // In the geometry we have to find a vertex channel that has a bone weight collection. + { + foreach (var geometry in mesh.Geometry) + { + foreach (var vertexChannel in geometry.Vertices.Channels) + { + if (vertexChannel is VertexChannel) + { + return true; + } + } + } + } + + return false; + } + + /// + /// If a node is skinned, we need to use the skinned model effect rather than basic effect. This function runs through + /// the geometry and finds the meshes that have bone weights associated and swaps in the skinned effect. + /// + private void SwapSkinnedMaterial(NodeContent node) + { + // It has to be a MeshContent node. + if (node is MeshContent mesh) + // In the geometry we have to find a vertex channel that has a bone weight collection. + { + foreach (var geometry in mesh.Geometry) + { + var swap = false; + foreach (var vertexChannel in geometry.Vertices.Channels) + { + if (vertexChannel is VertexChannel) + { + swap = true; + break; + } + } + + if (swap) + { + if (_toSkinnedMaterial.ContainsKey(geometry.Material)) + { + // We have already swapped it. + geometry.Material = _toSkinnedMaterial[geometry.Material]; + } + else + { + var skinnedMaterial = new SkinnedMaterialContent(); + + // Copy over the data. + if (geometry.Material is BasicMaterialContent basicMaterial) + { + skinnedMaterial.Alpha = basicMaterial.Alpha; + skinnedMaterial.DiffuseColor = basicMaterial.DiffuseColor; + skinnedMaterial.EmissiveColor = basicMaterial.EmissiveColor; + skinnedMaterial.SpecularColor = basicMaterial.SpecularColor; + skinnedMaterial.SpecularPower = basicMaterial.SpecularPower; + skinnedMaterial.Texture = basicMaterial.Texture; + } + + skinnedMaterial.WeightsPerVertex = 4; + + _toSkinnedMaterial[geometry.Material] = skinnedMaterial; + geometry.Material = skinnedMaterial; + } + } + } + } + + foreach (var child in node.Children) + { + SwapSkinnedMaterial(child); + } + } + + /// + /// Entry point for animation processing. + /// + private void ProcessAnimations(ModelContent model, NodeContent input) + { + // First build a lookup table so we can determine the index into the list of bones from a bone name. + for (var i = 0; i < model.Bones.Count; i++) + { + _bones[model.Bones[i].Name] = i; + } + + // For saving the bone transforms. + _boneTransforms = new Matrix[model.Bones.Count]; + + // Collect up all of the animation data. + ProcessAnimationsRecursive(input); + + // Ensure there is always a clip, even if none is included in the FBX. + // That way we can create poses using FBX files as one-frame animation clips. + if (_modelExtra.Clips.Count == 0) + { + var clip = new AnimationClip(); + _modelExtra.Clips.Add(clip); + + var clipName = "Take 001"; + + // Retain by name. + _clips[clipName] = clip; + + clip.Name = clipName; + foreach (var bone in model.Bones) + { + var clipBone = new AnimationBone(); + clipBone.Name = bone.Name; + + clip.Bones.Add(clipBone); + } + } + + // Ensure all animations have a first key frame for every bone. + foreach (var clip in _modelExtra.Clips) + { + for (var b = 0; b < _bones.Count; b++) + { + var keyframes = clip.Bones[b].Keyframes; + if (keyframes.Count == 0 || keyframes[0].Time > 0) + { + var keyframe = new Keyframe(); + keyframe.Time = 0; + keyframe.Transform = _boneTransforms[b]; + keyframes.Insert(0, keyframe); + } + } + } + } + + /// + /// Recursive function that processes the entire scene graph, collecting up all of the animation data. + /// + private void ProcessAnimationsRecursive(NodeContent input) + { + // Look up the bone for this input channel. + if (_bones.TryGetValue(input.Name, out var inputBoneIndex)) + { + // Save the transform. + _boneTransforms[inputBoneIndex] = input.Transform; + } + + foreach (var animation in input.Animations) + { + // Do we have this animation before? + var clipName = animation.Key; + + if (!_clips.TryGetValue(clipName, out var clip)) + { + // Never seen before clip. + clip = new AnimationClip(); + _modelExtra.Clips.Add(clip); + + // Retain by name. + _clips[clipName] = clip; + + clip.Name = clipName; + foreach (var bone in _model.Bones) + { + var clipBone = new AnimationBone(); + clipBone.Name = bone.Name; + + clip.Bones.Add(clipBone); + } + } + + // Ensure the duration is always set. + if (animation.Value.Duration.TotalSeconds > clip.Duration) + { + clip.Duration = animation.Value.Duration.TotalSeconds; + } + + // For each channel, determine the bone and then process all of the keyframes for that bone. + + foreach (var channel in animation.Value.Channels) + { + // What is the bone index? + if (!_bones.TryGetValue(channel.Key, out var boneIndex)) + { + continue; // Ignore if not a named bone. + } + + // An animation is useless if it is for a bone not assigned to any meshes at all. + if (UselessAnimationTest(boneIndex)) + { + continue; + } + + // I'm collecting up in a linked list so we can process the data and remove redundant keyframes. + var keyframes = new LinkedList(); + foreach (var keyframe in channel.Value) + { + // Keyframe transformation. + var transform = keyframe.Transform; + + var newKeyframe = new Keyframe(); + newKeyframe.Time = keyframe.Time.TotalSeconds; + newKeyframe.Transform = transform; + + keyframes.AddLast(newKeyframe); + } + + LinearKeyframeReduction(keyframes); + foreach (var keyframe in keyframes) + { + clip.Bones[boneIndex].Keyframes.Add(keyframe); + } + } + } + + foreach (var child in input.Children) + { + ProcessAnimationsRecursive(child); + } + } + + /// + /// This function filters out keyframes that can be approximated well with linear interpolation. + /// + private void LinearKeyframeReduction(LinkedList keyframes) + { + if (keyframes.Count < 3) + { + return; + } + + var node = keyframes.First.Next; + + while (node != null) + { + var next = node.Next; + if (next == null) + { + break; + } + + // Determine nodes before and after the current node. + var a = node.Previous.Value; + var b = node.Value; + var c = next.Value; + + var t = (float)((node.Value.Time - a.Time) / (next.Value.Time - a.Time)); + + var translation = Vector3.Lerp(a.Translation, c.Translation, t); + var rotation = Quaternion.Slerp(a.Rotation, c.Rotation, t); + + if ((translation - b.Translation).LengthSquared() < TinyLength && + Quaternion.Dot(rotation, b.Rotation) > TinyCosAngle) + { + keyframes.Remove(node); + } + + node = next; + } + } + + /// + /// Discard any animation not assigned to a mesh or the skeleton. + /// + private bool UselessAnimationTest(int boneId) + { + // If any mesh is assigned to this bone, it is not useless. + foreach (var mesh in _model.Meshes) + { + if (mesh.ParentBone.Index == boneId) + { + return false; + } + } + + // If this bone is in the skeleton, it is not useless. + foreach (var b in _modelExtra.Skeleton) + { + if (boneId == b) + { + return false; + } + } + + // Otherwise, it is useless. + return true; + } +} \ No newline at end of file diff --git a/TGC.MonoGame.TP/Animations/PipelineExtension/CustomPipelineManager.cs b/TGC.MonoGame.TP/Animations/PipelineExtension/CustomPipelineManager.cs new file mode 100644 index 000000000..9023ad314 --- /dev/null +++ b/TGC.MonoGame.TP/Animations/PipelineExtension/CustomPipelineManager.cs @@ -0,0 +1,113 @@ +using Microsoft.Extensions.Configuration; +using Microsoft.Xna.Framework.Content.Pipeline; +using Microsoft.Xna.Framework.Content.Pipeline.Serialization.Compiler; +using MonoGame.Framework.Content.Pipeline.Builder; +using System; +using System.IO; +using System.Linq; +using System.Reflection.Metadata; + + +namespace ThunderingTanks.Animation.PipelineExtensions; + +/// +/// TODO This class needs a refactor. +/// This class allows you to build content in runtime without the need of adding the resources in the mgcb. +/// Currently, it only builds fbx with animations. +/// +public class CustomPipelineManager : PipelineManager +{ + private readonly IConfigurationRoot _configuration; + + public CustomPipelineManager(string projectDir, string outputDir, string intermediateDir, + IConfigurationRoot configuration) : base(projectDir, outputDir, intermediateDir) + { + _configuration = configuration; + } + + /// + /// Provides methods for writing compiled binary format. + /// + public ContentCompiler Compiler { get; private set; } + + public static CustomPipelineManager CreateCustomPipelineManager(IConfigurationRoot configuration) + { + var binFolder = "bin/"; + var objFolder = "obj/"; + var contentFolder = "Content/"; + + // This code is from MonoGame.Content.Builder.BuildContent.Build(out int successCount, out int errorCount). + // TODO the folder logic can be load in the game a save in the configuration, to avoid this folder logic. + var projectDirectory = PathHelper.Normalize(AppDomain.CurrentDomain.BaseDirectory); + var projectContentDirectory = + PathHelper.Normalize(Path.GetFullPath(Path.Combine(projectDirectory, "../../../" + contentFolder))); + var outputPath = PathHelper.Normalize(Path.Combine(projectDirectory, contentFolder)); + var projectDirectoryParts = projectDirectory.Split(new[] { binFolder }, StringSplitOptions.None); + var intermediatePath = PathHelper.Normalize(Path.GetFullPath(Path.Combine(projectContentDirectory, + "../" + objFolder + projectDirectoryParts.Last()))); + + return new CustomPipelineManager(projectContentDirectory, outputPath, intermediatePath, configuration); + } + + public void BuildAnimationContent(string modelFilename) + { + var importContext = new PipelineImporterContext(this); + var importer = new FbxImporter(); + var nodeContent = + importer.Import(ProjectDirectory + modelFilename + ".fbx", importContext); + var animationProcessor = new AnimationProcessor(); + + var parameters = new OpaqueDataDictionary + { + { "ColorKeyColor", "0,0,0,0" }, + { "ColorKeyEnabled", "True" }, + { "DefaultEffect", "BasicEffect" }, + { "GenerateMipmaps", "True" }, + { "GenerateTangentFrames", "False" }, + { "PremultiplyTextureAlpha", "True" }, + { "PremultiplyVertexColors", "True" }, + { "ResizeTexturesToPowerOfTwo", "False" }, + { "RotationX", "0" }, + { "RotationY", "0" }, + { "RotationZ", "0" }, + { "Scale", "1" }, + { "SwapWindingOrder", "False" }, + { "TextureFormat", "Compressed" } + }; + + // Record what we're building and how. + var pipelineEvent = new PipelineBuildEvent + { + SourceFile = modelFilename, + DestFile = OutputDirectory + modelFilename + ".xnb", + Importer = ".fbx", + Processor = "Animation Processor", + Parameters = ValidateProcessorParameters("Animation Processor", parameters) + }; + + var processContext = new PipelineProcessorContext(this, pipelineEvent); + var modelContent = animationProcessor.Process(nodeContent, processContext); + + // Write the content to disk. + WriteXnb(modelContent, pipelineEvent); + } + + private void WriteXnb(object content, PipelineBuildEvent pipelineEvent) + { + // Make sure the output directory exists. + var outputFileDir = Path.GetDirectoryName(pipelineEvent.DestFile); + + Directory.CreateDirectory(outputFileDir); + + Compiler ??= new ContentCompiler(); + + // Write the XNB. + using (var stream = new FileStream(pipelineEvent.DestFile, FileMode.Create, FileAccess.Write, FileShare.None)) + { + Compiler.Compile(stream, content, Platform, Profile, CompressContent, OutputDirectory, outputFileDir); + } + + // Store the last write time of the output XNB here so we can verify it hasn't been tampered with. + pipelineEvent.DestTime = File.GetLastWriteTime(pipelineEvent.DestFile); + } +} \ No newline at end of file diff --git a/TGC.MonoGame.TP/Cameras/Camera.cs b/TGC.MonoGame.TP/Cameras/Camera.cs new file mode 100644 index 000000000..ba86b1d2f --- /dev/null +++ b/TGC.MonoGame.TP/Cameras/Camera.cs @@ -0,0 +1,97 @@ +using Microsoft.Xna.Framework; + +namespace ThunderingTanks.Cameras +{ + /// + /// The minimum behavior that a camera should have. + /// + public abstract class Camera + { + public const float DefaultFieldOfViewDegrees = MathHelper.PiOver4; + public const float DefaultNearPlaneDistance = 0.1f; + public const float DefaultFarPlaneDistance = 50000; + + public Camera(float aspectRatio, float nearPlaneDistance = DefaultNearPlaneDistance, + float farPlaneDistance = DefaultFarPlaneDistance) : this(aspectRatio, nearPlaneDistance, farPlaneDistance, + DefaultFieldOfViewDegrees) + { + } + + public Camera(float aspectRatio, float nearPlaneDistance, float farPlaneDistance, float fieldOfViewDegrees) + { + BuildProjection(aspectRatio, nearPlaneDistance, farPlaneDistance, fieldOfViewDegrees); + } + + /// + /// Aspect ratio, defined as view space width divided by height. + /// + public float AspectRatio { get; set; } + + /// + /// Distance to the far view plane. + /// + public float FarPlane { get; set; } + + /// + /// Field of view in the y direction, in radians. + /// + public float FieldOfView { get; set; } + + /// + /// Distance to the near view plane. + /// + public float NearPlane { get; set; } + + /// + /// Direction where the camera is looking. + /// + public Vector3 FrontDirection { get; set; } + + /// + /// The perspective projection matrix. + /// + public Matrix Projection { get; set; } + + /// + /// Position where the camera is located. + /// + public Vector3 Position { get; set; } + + /// + /// Represents the positive x-axis of the camera space. + /// + public Vector3 RightDirection { get; set; } + + /// + /// Vector up direction (may differ if the camera is reversed). + /// + public Vector3 UpDirection { get; set; } + + /// + /// The created view matrix. + /// + public Matrix View { get; set; } + + /// + /// Build a perspective projection matrix based on a field of view, aspect ratio, and near and far view plane + /// distances. + /// + /// The aspect ratio, defined as view space width divided by height. + /// The distance to the near view plane. + /// The distance to the far view plane. + /// The field of view in the y direction, in degrees. + public void BuildProjection(float aspectRatio, float nearPlaneDistance, float farPlaneDistance, + float fieldOfViewDegrees) + { + Projection = Matrix.CreatePerspectiveFieldOfView(fieldOfViewDegrees, aspectRatio, nearPlaneDistance, + farPlaneDistance); + } + + /// + /// Allows updating the internal state of the camera if this method is overwritten. + /// By default it does not perform any action. + /// + /// Holds the time state of a . + public abstract void Update(GameTime gameTime); + } +} \ No newline at end of file diff --git a/TGC.MonoGame.TP/Cameras/FreeCamera.cs b/TGC.MonoGame.TP/Cameras/FreeCamera.cs new file mode 100644 index 000000000..8fa9889fd --- /dev/null +++ b/TGC.MonoGame.TP/Cameras/FreeCamera.cs @@ -0,0 +1,155 @@ +using System; +using Microsoft.Xna.Framework; +using Microsoft.Xna.Framework.Input; +namespace ThunderingTanks.Cameras +{ + internal class FreeCamera : Camera + { + private readonly bool lockMouse; + private readonly Point screenCenter; + private bool changed; + + private Vector2 pastMousePosition; + private float pitch; + + // Angles + private float yaw = -90f; + + public FreeCamera(float aspectRatio, Vector3 position, Point screenCenter) : this(aspectRatio, position) + { + lockMouse = true; + this.screenCenter = screenCenter; + } + + public FreeCamera(float aspectRatio, Vector3 position) : base(aspectRatio) + { + Position = position; + pastMousePosition = Mouse.GetState().Position.ToVector2(); + UpdateCameraVectors(); + CalculateView(); + } + + public float MovementSpeed { get; set; } = 200f; + public float MouseSensitivity { get; set; } = 100f; + + private void CalculateView() + { + View = Matrix.CreateLookAt(Position, Position + FrontDirection, UpDirection); + } + + /// + public override void Update(GameTime gameTime) + { + var elapsedTime = (float)gameTime.ElapsedGameTime.TotalSeconds; + changed = false; + ProcessKeyboard(elapsedTime); + ProcessMouseMovement(elapsedTime); + + if (changed) + CalculateView(); + } + + private void ProcessKeyboard(float elapsedTime) + { + var keyboardState = Keyboard.GetState(); + + var currentMovementSpeed = MovementSpeed; + if (keyboardState.IsKeyDown(Keys.LeftShift)) + currentMovementSpeed *= 51f; + + if (keyboardState.IsKeyDown(Keys.Up)) + { + Position += FrontDirection * currentMovementSpeed * elapsedTime * 50f; ; + changed = true; + } + + if (keyboardState.IsKeyDown(Keys.Down)) + { + Position += -FrontDirection * currentMovementSpeed * elapsedTime * 50f; + changed = true; + } + + if (keyboardState.IsKeyDown(Keys.W)) + { + pitch += MouseSensitivity * elapsedTime; + if (pitch > 89.0f) + pitch = 89.0f; + changed = true; + UpdateCameraVectors(); + } + + if (keyboardState.IsKeyDown(Keys.S)) + { + pitch -= MouseSensitivity * elapsedTime; + if (pitch < -89.0f) + pitch = -89.0f; + changed = true; + UpdateCameraVectors(); + } + + if (keyboardState.IsKeyDown(Keys.A)) + { + yaw -= MouseSensitivity * elapsedTime; + changed = true; + UpdateCameraVectors(); + } + + if (keyboardState.IsKeyDown(Keys.D)) + { + yaw += MouseSensitivity * elapsedTime; + changed = true; + UpdateCameraVectors(); + } + } + + private void ProcessMouseMovement(float elapsedTime) + { + var mouseState = Mouse.GetState(); + + if (mouseState.RightButton.Equals(ButtonState.Pressed)) + { + var mouseDelta = mouseState.Position.ToVector2() - pastMousePosition; + mouseDelta *= MouseSensitivity * elapsedTime; + + yaw -= mouseDelta.X; + pitch += mouseDelta.Y; + + if (pitch > 89.0f) + pitch = 89.0f; + if (pitch < -89.0f) + pitch = -89.0f; + + changed = true; + UpdateCameraVectors(); + + if (lockMouse) + { + Mouse.SetPosition(screenCenter.X, screenCenter.Y); + Mouse.SetCursor(MouseCursor.Crosshair); + } + else + { + Mouse.SetCursor(MouseCursor.Arrow); + } + } + + pastMousePosition = Mouse.GetState().Position.ToVector2(); + } + + private void UpdateCameraVectors() + { + // Calculate the new Front vector + Vector3 tempFront; + tempFront.X = MathF.Cos(MathHelper.ToRadians(yaw)) * MathF.Cos(MathHelper.ToRadians(pitch)); + tempFront.Y = MathF.Sin(MathHelper.ToRadians(pitch)); + tempFront.Z = MathF.Sin(MathHelper.ToRadians(yaw)) * MathF.Cos(MathHelper.ToRadians(pitch)); + + FrontDirection = Vector3.Normalize(tempFront); + + // Also re-calculate the Right and Up vector + // Normalize the vectors, because their length gets closer to 0 the more you look up or down which results in slower movement. + RightDirection = Vector3.Normalize(Vector3.Cross(FrontDirection, Vector3.Up)); + UpDirection = Vector3.Normalize(Vector3.Cross(RightDirection, FrontDirection)); + } + } +} diff --git a/TGC.MonoGame.TP/Cameras/SimpleCamera.cs b/TGC.MonoGame.TP/Cameras/SimpleCamera.cs new file mode 100644 index 000000000..10c9d17c1 --- /dev/null +++ b/TGC.MonoGame.TP/Cameras/SimpleCamera.cs @@ -0,0 +1,125 @@ +using System; +using Microsoft.Xna.Framework; +using Microsoft.Xna.Framework.Input; + +namespace ThunderingTanks.Cameras +{ + /// + /// Camera with simple movement. + /// + public class SimpleCamera : Camera + { + /// + /// Forward direction of the camera. + /// + public readonly Vector3 DefaultWorldFrontVector = Vector3.Forward; + + /// + /// The direction that is "up" from the camera's point of view. + /// + public readonly Vector3 DefaultWorldUpVector = Vector3.Up; + + /// + /// Camera with simple movement to be able to move in the 3D world, which has the up vector in (0,1,0) and the forward + /// vector in (0,0,-1). + /// + /// Aspect ratio, defined as view space width divided by height. + /// The position of the camera. + /// The speed of movement. + /// The angle of movement. + public SimpleCamera(float aspectRatio, Vector3 position, float speed, float angle) : base(aspectRatio) + { + BuildView(position, speed, angle); + } + + /// + /// Camera with simple movement to be able to move in the 3D world, which has the up vector in (0,1,0) and the forward + /// vector in (0,0,-1). + /// + /// Aspect ratio, defined as view space width divided by height. + /// The position of the camera. + /// The speed of movement. + /// The angle of movement. + /// Distance to the near view plane. + /// Distance to the far view plane. + public SimpleCamera(float aspectRatio, Vector3 position, float speed, float angle, float nearPlaneDistance, + float farPlaneDistance) : base(aspectRatio, nearPlaneDistance, farPlaneDistance) + { + BuildView(position, speed, angle); + } + + /// + /// Value with which the camera is going to move. + /// + public float Speed { get; set; } + + /// + /// Value with which the camera is going to move the angle. + /// + public float Angle { get; set; } + + /// + /// Build view matrix and update the internal directions. + /// + /// The position of the camera. + /// The speed of movement. + /// The angle of movement. + private void BuildView(Vector3 position, float speed, float angle) + { + Position = position; + FrontDirection = DefaultWorldFrontVector; + Speed = speed; + Angle = angle; + View = Matrix.CreateLookAt(Position, Position + FrontDirection, DefaultWorldUpVector); + } + + /// + public override void Update(GameTime gameTime) + { + var keyboardState = Keyboard.GetState(); + var time = Convert.ToSingle(gameTime.ElapsedGameTime.TotalSeconds); + + // Check for input to rotate the camera. + var pitch = 0f; + var turn = 0f; + + if (keyboardState.IsKeyDown(Keys.Up)) + pitch += time * Angle; + + if (keyboardState.IsKeyDown(Keys.Down)) + pitch -= time * Angle; + + if (keyboardState.IsKeyDown(Keys.Left)) + turn += time * Angle; + + if (keyboardState.IsKeyDown(Keys.Right)) + turn -= time * Angle; + + RightDirection = Vector3.Cross(DefaultWorldUpVector, FrontDirection); + var flatFront = Vector3.Cross(RightDirection, DefaultWorldUpVector); + + var pitchMatrix = Matrix.CreateFromAxisAngle(RightDirection, pitch); + var turnMatrix = Matrix.CreateFromAxisAngle(DefaultWorldUpVector, turn); + + var tiltedFront = Vector3.TransformNormal(FrontDirection, pitchMatrix * turnMatrix); + + // Check angle so we can't flip over. + if (Vector3.Dot(tiltedFront, flatFront) > 0.001f) FrontDirection = Vector3.Normalize(tiltedFront); + + // Check for input to move the camera around. + if (keyboardState.IsKeyDown(Keys.W)) + Position += FrontDirection * time * Speed; + + if (keyboardState.IsKeyDown(Keys.S)) + Position -= FrontDirection * time * Speed; + + if (keyboardState.IsKeyDown(Keys.A)) + Position += RightDirection * time * Speed; + + if (keyboardState.IsKeyDown(Keys.D)) + Position -= RightDirection * time * Speed; + + View = Matrix.CreateLookAt(Position, Position + FrontDirection, DefaultWorldUpVector); + } + } +} \ No newline at end of file diff --git a/TGC.MonoGame.TP/Cameras/StaticCamera.cs b/TGC.MonoGame.TP/Cameras/StaticCamera.cs new file mode 100644 index 000000000..0b30d93b0 --- /dev/null +++ b/TGC.MonoGame.TP/Cameras/StaticCamera.cs @@ -0,0 +1,40 @@ +using Microsoft.Xna.Framework; + +namespace ThunderingTanks.Cameras +{ + /// + /// Static camera without restrictions, where each component is configured and nothing is inferred. + /// + public class StaticCamera : Camera + { + /// + /// Static camera looking at a particular direction, which has the up vector (0,1,0). + /// + /// Aspect ratio, defined as view space width divided by height. + /// The position of the camera. + /// The direction where the camera is pointing. + /// The direction that is "up" from the camera's point of view. + public StaticCamera(float aspectRatio, Vector3 position, Vector3 frontDirection, Vector3 upDirection) : base( + aspectRatio) + { + Position = position; + FrontDirection = frontDirection; + UpDirection = upDirection; + BuildView(); + } + + /// + /// Build the camera View matrix using its properties. + /// + public void BuildView() + { + View = Matrix.CreateLookAt(Position, Position + FrontDirection, UpDirection); + } + + /// + public override void Update(GameTime gameTime) + { + // This camera has no movement, once initialized with position and lookAt it is no longer updated automatically. + } + } +} \ No newline at end of file diff --git a/TGC.MonoGame.TP/Cameras/TargetCamera.cs b/TGC.MonoGame.TP/Cameras/TargetCamera.cs new file mode 100644 index 000000000..2bb4feb97 --- /dev/null +++ b/TGC.MonoGame.TP/Cameras/TargetCamera.cs @@ -0,0 +1,103 @@ +using Microsoft.Xna.Framework; + +namespace ThunderingTanks.Cameras +{ + /// + /// Camera looking at a particular point, assumes the up vector is in y. + /// + + public class TargetCamera : Camera + { + private float _cameraFollowRadius = InitialCameraFollowRadius; + + private const float MaxCameraFollowRadius = 100f; + private const float MinCameraFollowRadius = 30f; + private const float InitialCameraFollowRadius = 1300f; + private const float RadiusIncrement = 10f; + private const float CameraUpDistance = 15f; + + /// + /// The direction that is "up" from the camera's point of view. + /// + + public readonly Vector3 DefaultWorldUpVector = Vector3.Up; + + /// + /// Camera looking at a particular direction, which has the up vector (0,1,0). + /// + + /// Aspect ratio, defined as view space width divided by height. + /// The position of the camera. + /// The target towards which the camera is pointing. + + public TargetCamera(float aspectRatio, Vector3 position, Vector3 targetPosition) : base(aspectRatio) + { + BuildView(position, targetPosition); + } + + /// + /// Camera looking at a particular direction, which has the up vector (0,1,0). + /// + + /// Aspect ratio, defined as view space width divided by height. + /// The position of the camera. + /// The target towards which the camera is pointing. + /// Distance to the near view plane. + /// Distance to the far view plane. + + public TargetCamera(float aspectRatio, Vector3 position, Vector3 targetPosition, float nearPlaneDistance, + float farPlaneDistance) : base(aspectRatio, nearPlaneDistance, farPlaneDistance) + { + BuildView(position, targetPosition); + } + + /// + /// The target towards which the camera is pointing. + /// + + public Vector3 TargetPosition { get; set; } + + /// + /// Build view matrix and update the internal directions. + /// + + /// The position of the camera. + /// The target towards which the camera is pointing. + + private void BuildView(Vector3 position, Vector3 targetPosition) + { + Position = position; + TargetPosition = targetPosition; + BuildView(); + } + + /// + /// Build view matrix and update the internal directions. + /// + + public void BuildView() + { + FrontDirection = Vector3.Normalize(TargetPosition - Position); + RightDirection = Vector3.Normalize(Vector3.Cross(DefaultWorldUpVector, FrontDirection)); + UpDirection = Vector3.Cross(FrontDirection, RightDirection); + View = Matrix.CreateLookAt(Position, FrontDirection + Position, UpDirection); + } + + public override void Update(GameTime gameTime) + { + // This camera has no movement, once initialized with position and lookAt it is no longer updated automatically. + } + + public void Update(Vector3 targetPosition, float yaw) + { + var playerBackDirection = Vector3.Transform(Vector3.Backward, Matrix.CreateRotationY(yaw)); + var orbitalPosition = _cameraFollowRadius * playerBackDirection; + var upDistance = Vector3.Up * CameraUpDistance; + var newCameraPosition = targetPosition + orbitalPosition + upDistance; + + Position = newCameraPosition; + TargetPosition = targetPosition; + BuildView(); + } + } +} \ No newline at end of file diff --git a/TGC.MonoGame.TP/Collisions/BoundingCilinder.cs b/TGC.MonoGame.TP/Collisions/BoundingCilinder.cs new file mode 100644 index 000000000..fe1a13343 --- /dev/null +++ b/TGC.MonoGame.TP/Collisions/BoundingCilinder.cs @@ -0,0 +1,554 @@ +using Microsoft.Xna.Framework; +using System; +using System.Collections.Generic; +using System.Text; + +namespace ThunderingTanks.Collisions +{ + + /// + /// Represents a Bounding Cylinder to test for intersections + /// + public class BoundingCylinder + { + // The center of the Cylinder in World Space + private Vector3 _center; + + // The radius of the Cylinder + private float _radius; + + // The distance from the Cylinder center to either its top or bottom + private float _halfHeight; + + // A matrix describing the Cylinder rotation + private Matrix _rotation; + + + // Matrices + // These are used to test for intersections, and serve to transform points to the Cylinder space or vice versa + + + // The opposite of the translation matrix, to calculate the InverseTransform + private Matrix _oppositeTranslation; + + // The inverse of the rotation matrix, to calculate the InverseTransform + private Matrix _inverseRotation; + + // An internal matrix to transform points from Cylinder space back to local space + private Matrix _inverseTransform; + + // An internal scale matrix to calculate the final Transform matrix + private Matrix _scale; + + // An internal translation matrix to calculate the final Transform matrix + private Matrix _translation; + + + /// + /// The center of the Cylinder in World Space + /// + public Vector3 Center + { + get => _center; + set + { + _center = value; + UpdateTranslation(); + UpdateInverseRotation(); + UpdateTransform(); + } + } + + /// + /// The radius of the Cylinder + /// + public float Radius + { + get => _radius; + set + { + _radius = value; + UpdateScale(); + UpdateTransform(); + } + } + + /// + /// The distance from the Cylinder center to either its top or bottom + /// + public float HalfHeight + { + get => _halfHeight; + set + { + _halfHeight = value; + UpdateScale(); + UpdateTransform(); + } + } + + /// + /// A matrix describing the Cylinder rotation + /// + public Matrix Rotation + { + get => _rotation; + set + { + _rotation = value; + IsXZAligned = _rotation.Equals(Matrix.Identity); + UpdateInverseRotation(); + UpdateTransform(); + } + } + + + // An internal matrix to transform points from local space to Cylinder space + public Matrix Transform { get; private set; } + + /// + /// True if this Cylinder has no rotation, and its circular shape is aligned to the XZ plane + /// + public bool IsXZAligned { get; private set; } + + + + /// + /// Creates a Bounding Cylinder with a center, radius and half-length. Note that it is XZ aligned. + /// + /// The center of the cylinder. + /// The horizontal radius of the cylinder. + /// Half the height of the cylinder. + public BoundingCylinder(Vector3 center, float radius, float halfLength) + { + _center = center; + _radius = radius; + _halfHeight = halfLength; + _rotation = Matrix.Identity; + IsXZAligned = true; + + UpdateTranslation(); + UpdateScale(); + UpdateInverseRotation(); + UpdateTransform(); + } + + /// + /// Moves the Cylinder center by a delta offset, and updates the internal values of the Cylinder. + /// + /// The amount of translation on each axis + public void Move(Vector3 delta) + { + _center += delta; + + UpdateTranslation(); + UpdateInverseRotation(); + UpdateTransform(); + } + + /// + /// Rotates the Cylinder using a rotation matrix. Considers the previous rotation and applies the new one. + /// Then it updates the internal values of the Cylinder. + /// + /// The rotation matrix to apply to the Cylinder + public void Rotate(Matrix rotation) + { + _rotation *= rotation; + IsXZAligned = _rotation.Equals(Matrix.Identity); + UpdateInverseRotation(); + UpdateTransform(); + } + + /// + /// Rotates the Cylinder using a quaternion. Considers the previous rotation and applies the new one. + /// Then it updates the internal values of the Cylinder. + /// + /// The rotation quaternion to apply to the Cylinder + public void Rotate(Quaternion rotation) + { + Rotate(Matrix.CreateFromQuaternion(rotation)); + } + + + /// + /// Check if this intersects a . + /// + /// The to test for intersection. + /// + /// true if this intersects , + /// false if it does not. + /// + public bool Intersects(Ray ray) + { + var origin = Vector3.Transform(ray.Position, _inverseTransform); + var direction = Vector3.TransformNormal(ray.Direction, _inverseTransform); + + var x0 = origin.X; + var xt = direction.X; + var y0 = origin.Y; + var yt = direction.Y; + var z0 = origin.Z; + var zt = direction.Z; + + // Note: This solution is based on these equations + // x^2 + z^2 = 1, -1 <= y <= 1 | For the cylinder + // (x, y, z) = (x0, y0, z0) + t * (xt, yt, zt) | For the ray + + float t1, t2; + + if (yt == 0) + { + if (y0 > 1) return false; + if (y0 < -1) return false; + t1 = float.MinValue; + t2 = float.MaxValue; + } + else + { + t1 = (-1 - y0) / yt; + t2 = (1 - y0) / yt; + } + + float a = xt * xt + zt * zt, + b = 2 * x0 * xt + 2 * z0 * zt, + c = x0 * x0 + z0 * z0 - 1; + + var root = b * b - 4 * a * c; + + if (root < 0) return false; + if (root == 0) + { + var t = -b / (2 * a); + return t >= t1 && t <= t2; + } + var up = -b; + var down = 2 * a; + var sqrt = MathF.Sqrt(root); + + float t3, t4; + t3 = (up - sqrt) / down; + t4 = (up + sqrt) / down; + + if (t3 <= t1 && t4 >= t2) return true; + if (t3 >= t1 && t3 <= t2) return true; + if (t4 >= t1 && t4 <= t2) return true; + return false; + } + + /// + /// Check if this contains a point. + /// + /// The to test. + /// + /// if this contains + /// or if it does not. + /// + public ContainmentType Contains(Vector3 point) + { + var transformedPoint = Vector3.Transform(point, _inverseRotation); + + if (MathF.Abs(_center.Y - transformedPoint.Y) > _halfHeight) + return ContainmentType.Disjoint; + + var centerToPoint = transformedPoint - _center; + + var squaredPointX = centerToPoint.X * centerToPoint.X; + var squaredPointZ = centerToPoint.Z * centerToPoint.Z; + var squaredRadius = _radius * _radius; + + return ((squaredPointX + squaredPointZ) <= squaredRadius) ? ContainmentType.Contains : ContainmentType.Disjoint; + } + + + /// + /// Gets the closest point in a cylinder from a point. + /// + /// The point from which to find the closest position. + /// A position in the cylinder that is the closest to + private Vector3 ClosestPoint(Vector3 point) + { + // Transform the point to cylindrical UVW coordinates + var uvwPoint = Vector3.Transform(point, _inverseRotation); + + // Find the closest point in UVW coordinates + + var direction = uvwPoint - _center; + direction.Y = 0; + if (direction.LengthSquared() > (_radius * _radius)) + { + direction.Normalize(); + direction *= _radius; + } + + var distanceY = uvwPoint.Y - _center.Y; + if (MathF.Abs(distanceY) > _halfHeight) + return _center + new Vector3(0, _halfHeight, 0) * Math.Sign(distanceY) + direction; + + var uvwResult = _center + new Vector3(0, distanceY, 0) + direction; + + + + + // Transform that result back to world coordinates + var translatedRotation = Matrix.Invert(_inverseRotation); + return Vector3.Transform(uvwResult, translatedRotation); + } + + + + /// + /// Check if this intersects a . + /// + /// The to test for intersection. + /// + /// true if this intersects , + /// false if it does not. + /// + public bool Intersects(BoundingSphere sphere) + { + // Transform the sphere center to cylindrical UVW coordinates + var uvwSphereCenter = Vector3.Transform(sphere.Center, _inverseRotation); + + // We check if there is intersection in UVW space + + var sphereRadius = sphere.Radius; + var distanceY = MathF.Abs(uvwSphereCenter.Y - _center.Y); + + // If the sphere is way too high or too low there is no intersection + if (distanceY > _halfHeight + sphereRadius) + return false; + + var centerToCenter = uvwSphereCenter - _center; + centerToCenter.Y = 0; + + var addedRadius = _radius + sphereRadius; + + // If the sphere is too far in the XZ plane there is no intersection + if (centerToCenter.LengthSquared() > (addedRadius * addedRadius)) + return false; + + // If the sphere's center is inside the Y coordinates of the cylinder, there is an intersection + if (distanceY < _halfHeight) + return true; + + // Check if the closest point to the center of the sphere belongs to the cylinder + centerToCenter.Normalize(); + centerToCenter *= _radius; + centerToCenter.Y = _halfHeight * MathF.Sign(uvwSphereCenter.Y - _center.Y); + centerToCenter += _center; + + return (centerToCenter - uvwSphereCenter).LengthSquared() <= (sphereRadius * sphereRadius); + } + + + /// + /// Check if this intersects a Line Segment. + /// + /// The start point of the Line Segment to test for intersection. + /// The end point of the Line Segment to test for intersection. + /// + /// true if this intersects with the Line Segment, + /// false if it does not. + /// + public Vector3? Intersects(Vector3 pointA, Vector3 pointB) + { + var halfHeight = Vector3.TransformNormal(Vector3.Up, Transform); + var cylinderInit = _center - halfHeight; + var cylinderEnd = _center + halfHeight; + + var t = -1f; + var q = Vector3.Zero; + + Vector3 d = cylinderEnd - cylinderInit, m = pointA - cylinderInit, n = pointB - pointA; + var md = Vector3.Dot(m, d); + var nd = Vector3.Dot(n, d); + var dd = Vector3.Dot(d, d); + + // Test if segment fully outside either endcap of cylinder + if (md < 0.0f && md + nd < 0.0f) return null; // Segment outside ’p’ side of cylinder + if (md > dd && md + nd > dd) return null; // Segment outside ’q’ side of cylinder + var nn = Vector3.Dot(n, n); + var mn = Vector3.Dot(m, n); + var a = dd * nn - nd * nd; + var k = Vector3.Dot(m, m) - _radius * _radius; + var c = dd * k - md * md; + if (MathF.Abs(a) < float.Epsilon) + { + // Segment runs parallel to cylinder axis + if (c > 0.0f) + return null; // 'a' and thus the segment lie outside cylinder + // Now known that segment intersects cylinder; figure out how it intersects + if (md < 0.0f) + t = -mn / nn; // Intersect segment against 'p' endcap + else if (md > dd) + t = (nd - mn) / nn; // Intersect segment against ’q’ endcap + else + t = 0.0f; // 'a' lies inside cylinder + q = pointA + t * n; + return q; + } + var b = dd * mn - nd * md; + var discr = b * b - a * c; + if (discr < 0.0f) + return null; // No real roots; no intersection + t = (-b - MathF.Sqrt(discr)) / a; + if (t < 0.0f || t > 1.0f) + return null; // Intersection lies outside segment + + if (md + t * nd < 0.0f) + { + // Intersection outside cylinder on 'p' side + if (nd <= 0.0f) + return null; // Segment pointing away from endcap + t = -md / nd; + // Keep intersection if Dot(S(t) - p, S(t) - p) <= r^2 + if (k + t * (2.0f * mn + t * nn) <= 0.0f) + return q; + else + return null; + } + if (md + t * nd > dd) + { + // Intersection outside cylinder on 'q' side + if (nd >= 0.0f) + return null; // Segment pointing away from endcap + t = (dd - md) / nd; + // Keep intersection if Dot(S(t) - q, S(t) - q) <= r^2 + if (k + dd - 2.0f * md + t * (2.0f * (mn - nd) + t * nn) <= 0.0f) + return q; + else + return null; + } + + // Segment intersects cylinder between the endcaps; t is correct + q = pointA + t * n; + return q; + } + + + public static Vector3 ClosestPoint(BoundingBox box, Vector3 point) + { + var min = box.Min; + var max = box.Max; + point.X = MathHelper.Clamp(point.X, min.X, max.X); + point.Y = MathHelper.Clamp(point.Y, min.Y, max.Y); + point.Z = MathHelper.Clamp(point.Z, min.Z, max.Z); + return point; + } + + + /// + /// Check if this intersects a . + /// + /// The box to test for intersection. + /// A indicating if the bounding volumes intersect with each other. + public BoxCylinderIntersection Intersects(BoundingBox box) + { + if (IsXZAligned) + return IntersectsXZAligned(box); + else + // TODO: Implement the method from + // https://github.com/teikitu/teikitu_release/blob/master/teikitu/src/TgS%20COLLISION/TgS%20Collision%20-%20F%20-%20Cylinder-Box.c_inc + throw new NotImplementedException(); + } + + /// + /// Check if this , assumed XZ aligned, intersects a . + /// + /// The box to test for intersection. + /// A indicating if the bounding volumes intersect with each other. + public BoxCylinderIntersection IntersectsXZAligned(BoundingBox box) + { + // Calculate the closest point + var closestPoint = ClosestPoint(box, _center); + + // Is closest point the same as the center? + // This means that the center is inside the box + if (closestPoint.Equals(_center)) + return BoxCylinderIntersection.Intersecting; + + // Distance in Y, is it greater, less, or in the center? + var differenceInY = MathF.Abs(closestPoint.Y - _center.Y); + + // If the absolute of the distance is greater than half the height, we are not intersecting + if (differenceInY > _halfHeight) + return BoxCylinderIntersection.None; + + var radiusSquared = _radius * _radius; + var centerDistance = new Vector2(_center.X - closestPoint.X, _center.Z - closestPoint.Z); + var differenceInRadius = centerDistance.LengthSquared() - radiusSquared; + + // If the distance is equal, this means that we are on the top/bottom faces + // We are colliding on the top or bottom, so check if we are in the radius. + // We are either on the edge or not colliding + if (differenceInY == _halfHeight) + return (differenceInRadius <= 0f) ? BoxCylinderIntersection.Edge : BoxCylinderIntersection.None; + + // If we got here, the closest point is not at the top/bottom + // It depends on our distance to classify the intersection + + if (differenceInRadius == 0f) + return BoxCylinderIntersection.Edge; + else if (differenceInRadius < 0f) + return BoxCylinderIntersection.Intersecting; + else + return BoxCylinderIntersection.None; + } + + + + /// + /// Updates the Translation matrix and the Opposite Translation matrix as well, + /// based on the contents of . + /// + private void UpdateTranslation() + { + _translation = Matrix.CreateTranslation(_center); + _oppositeTranslation = Matrix.CreateTranslation(-_center); + } + + /// + /// Updates the Scale matrix based on the contents of and . + /// + private void UpdateScale() + { + _scale = Matrix.CreateScale(_radius, _halfHeight, _radius); + } + + /// + /// Updates the Inverse Rotation matrix, used in intersection tests, based on the values of , + /// and . + /// + private void UpdateInverseRotation() + { + _inverseRotation = + _oppositeTranslation * + Matrix.Invert(_rotation) * + _translation; + } + + /// + /// Updates the Transform and Inverse Transform matrices, based on the values of , and . + /// + private void UpdateTransform() + { + Transform = _scale * _rotation * _translation; + _inverseTransform = Matrix.Invert(Transform); + } + } + + + /// + /// Describes the type of intersection a and a had. + /// + public enum BoxCylinderIntersection + { + ///The box touches the cylinder at an edge. Penetration is zero. + Edge, + ///The box touches the cylinder. Penetration is more than zero. + Intersecting, + ///The box and the cylinder do not intersect. + None, + } + +} diff --git a/TGC.MonoGame.TP/Collisions/BoundingVolumesExtensions.cs b/TGC.MonoGame.TP/Collisions/BoundingVolumesExtensions.cs new file mode 100644 index 000000000..23da85960 --- /dev/null +++ b/TGC.MonoGame.TP/Collisions/BoundingVolumesExtensions.cs @@ -0,0 +1,150 @@ +using Microsoft.Xna.Framework; +using Microsoft.Xna.Framework.Graphics; +using System; + +namespace ThunderingTanks.Collisions +{ + public static class BoundingVolumesExtensions + { + public static Vector3 GetExtents(BoundingBox box) + { + var max = box.Max; + var min = box.Min; + + return (max - min) * 0.5f; + } + public static float GetVolume(BoundingBox box) + { + var difference = box.Max - box.Min; + return difference.X * difference.Y * difference.Z; + } + public static Vector3 GetCenter(BoundingBox box) + { + return (box.Max + box.Min) * 0.5f; + } + public static BoundingBox Scale(BoundingBox box, float scale) + { + var center = GetCenter(box); + var extents = GetExtents(box); + var scaledExtents = extents * scale; + + return new BoundingBox(center - scaledExtents, center + scaledExtents); + } + public static BoundingBox Scale(BoundingBox box, Vector3 scale) + { + var center = GetCenter(box); + var extents = GetExtents(box); + var scaledExtents = extents * scale; + + return new BoundingBox(center - scaledExtents, center + scaledExtents); + } + public static Vector3 ClosestPoint(BoundingBox box, Vector3 point) + { + var min = box.Min; + var max = box.Max; + point.X = MathHelper.Clamp(point.X, min.X, max.X); + point.Y = MathHelper.Clamp(point.Y, min.Y, max.Y); + point.Z = MathHelper.Clamp(point.Z, min.Z, max.Z); + return point; + } + public static Vector3 GetNormalFromPoint(BoundingBox box, Vector3 point) + { + var normal = Vector3.Zero; + var min = float.MaxValue; + + point -= GetCenter(box); + var extents = GetExtents(box); + + var distance = MathF.Abs(extents.X - Math.Abs(point.X)); + if (distance < min) + { + min = distance; + normal = Math.Sign(point.X) * Vector3.UnitX; + } + distance = Math.Abs(extents.Y - Math.Abs(point.Y)); + if (distance < min) + { + min = distance; + normal = Math.Sign(point.Y) * Vector3.UnitY; + } + distance = Math.Abs(extents.Z - Math.Abs(point.Z)); + if (distance < min) + { + normal = Math.Sign(point.Z) * Vector3.UnitZ; + } + return normal; + } + public static BoundingBox FromMatrix(Matrix matrix) + { + return new BoundingBox(Vector3.Transform(-Vector3.One * 0.5f, matrix), Vector3.Transform(Vector3.One * 0.5f, matrix)); + } + public static BoundingBox CreateAABBFrom(Model model) + { + var minPoint = Vector3.One * float.MaxValue; + var maxPoint = Vector3.One * float.MinValue; + + var transforms = new Matrix[model.Bones.Count]; + model.CopyAbsoluteBoneTransformsTo(transforms); + + var meshes = model.Meshes; + for (int index = 0; index < meshes.Count; index++) + { + var meshParts = meshes[index].MeshParts; + for (int subIndex = 0; subIndex < meshParts.Count; subIndex++) + { + var vertexBuffer = meshParts[subIndex].VertexBuffer; + var declaration = vertexBuffer.VertexDeclaration; + var vertexSize = declaration.VertexStride / sizeof(float); + + var rawVertexBuffer = new float[vertexBuffer.VertexCount * vertexSize]; + vertexBuffer.GetData(rawVertexBuffer); + + for (var vertexIndex = 0; vertexIndex < rawVertexBuffer.Length; vertexIndex += vertexSize) + { + var transform = transforms[meshes[index].ParentBone.Index]; + var vertex = new Vector3(rawVertexBuffer[vertexIndex], rawVertexBuffer[vertexIndex + 1], rawVertexBuffer[vertexIndex + 2]); + vertex = Vector3.Transform(vertex, transform); + minPoint = Vector3.Min(minPoint, vertex); + maxPoint = Vector3.Max(maxPoint, vertex); + } + } + } + return new BoundingBox(minPoint, maxPoint); + } + public static BoundingSphere CreateSphereFrom(Model model) + { + var minPoint = Vector3.One * float.MaxValue; + var maxPoint = Vector3.One * float.MinValue; + + var transforms = new Matrix[model.Bones.Count]; + model.CopyAbsoluteBoneTransformsTo(transforms); + + var meshes = model.Meshes; + for (var index = 0; index < meshes.Count; index++) + { + var meshParts = meshes[index].MeshParts; + for (var subIndex = 0; subIndex < meshParts.Count; subIndex++) + { + var vertexBuffer = meshParts[subIndex].VertexBuffer; + var declaration = vertexBuffer.VertexDeclaration; + int vertexSize = declaration.VertexStride / sizeof(float); + + var rawVertexBuffer = new float[vertexBuffer.VertexCount * vertexSize]; + vertexBuffer.GetData(rawVertexBuffer); + + for (var vertexIndex = 0; vertexIndex < rawVertexBuffer.Length; vertexIndex += vertexSize) + { + var transform = transforms[meshes[index].ParentBone.Index]; + var vertex = new Vector3(rawVertexBuffer[vertexIndex], rawVertexBuffer[vertexIndex + 1], rawVertexBuffer[vertexIndex + 2]); + vertex = Vector3.Transform(vertex, transform); + minPoint = Vector3.Min(minPoint, vertex); + maxPoint = Vector3.Max(maxPoint, vertex); + } + } + } + var difference = (maxPoint - minPoint) * 0.5f; + return new BoundingSphere(difference, difference.Length()); + } + + } +} diff --git a/TGC.MonoGame.TP/Collisions/CollisionsClass.cs b/TGC.MonoGame.TP/Collisions/CollisionsClass.cs new file mode 100644 index 000000000..aa773b116 --- /dev/null +++ b/TGC.MonoGame.TP/Collisions/CollisionsClass.cs @@ -0,0 +1,126 @@ +using Microsoft.Xna.Framework; +using Microsoft.Xna.Framework.Graphics; + +namespace ThunderingTanks.Collisions +{ + public static class CollisionsClass + { + + public static BoundingBox CreateAABBFrom(Model model) + { + var minPoint = Vector3.One * float.MaxValue; + var maxPoint = Vector3.One * float.MinValue; + + var transforms = new Matrix[model.Bones.Count]; + model.CopyAbsoluteBoneTransformsTo(transforms); + + var meshes = model.Meshes; + for (int index = 0; index < meshes.Count; index++) + { + var meshParts = meshes[index].MeshParts; + for (int subIndex = 0; subIndex < meshParts.Count; subIndex++) + { + var vertexBuffer = meshParts[subIndex].VertexBuffer; + var declaration = vertexBuffer.VertexDeclaration; + var vertexSize = declaration.VertexStride / sizeof(float); + + var rawVertexBuffer = new float[vertexBuffer.VertexCount * vertexSize]; + vertexBuffer.GetData(rawVertexBuffer); + + for (var vertexIndex = 0; vertexIndex < rawVertexBuffer.Length; vertexIndex += vertexSize) + { + var transform = transforms[meshes[index].ParentBone.Index]; + var vertex = new Vector3(rawVertexBuffer[vertexIndex], rawVertexBuffer[vertexIndex + 1], rawVertexBuffer[vertexIndex + 2]); + vertex = Vector3.Transform(vertex, transform); + minPoint = Vector3.Min(minPoint, vertex); + maxPoint = Vector3.Max(maxPoint, vertex); + } + } + } + return new BoundingBox(minPoint, maxPoint); + } + + public static BoundingSphere CreateSphereFrom(Model model) + { + var minPoint = Vector3.One * float.MaxValue; + var maxPoint = Vector3.One * float.MinValue; + + var transforms = new Matrix[model.Bones.Count]; + model.CopyAbsoluteBoneTransformsTo(transforms); + + var meshes = model.Meshes; + for (var index = 0; index < meshes.Count; index++) + { + var meshParts = meshes[index].MeshParts; + for (var subIndex = 0; subIndex < meshParts.Count; subIndex++) + { + var vertexBuffer = meshParts[subIndex].VertexBuffer; + var declaration = vertexBuffer.VertexDeclaration; + int vertexSize = declaration.VertexStride / sizeof(float); + + var rawVertexBuffer = new float[vertexBuffer.VertexCount * vertexSize]; + vertexBuffer.GetData(rawVertexBuffer); + + for (var vertexIndex = 0; vertexIndex < rawVertexBuffer.Length; vertexIndex += vertexSize) + { + var transform = transforms[meshes[index].ParentBone.Index]; + var vertex = new Vector3(rawVertexBuffer[vertexIndex], rawVertexBuffer[vertexIndex + 1], rawVertexBuffer[vertexIndex + 2]); + vertex = Vector3.Transform(vertex, transform); + minPoint = Vector3.Min(minPoint, vertex); + maxPoint = Vector3.Max(maxPoint, vertex); + } + } + } + var difference = (maxPoint - minPoint) * 0.5f; + return new BoundingSphere(difference, difference.Length()); + } + + public static BoundingBox CreateBoundingBox(Model model, Matrix escala, Vector3 position) + { + var minPoint = Vector3.One * float.MaxValue; + var maxPoint = Vector3.One * float.MinValue; + + var transforms = new Matrix[model.Bones.Count]; + model.CopyAbsoluteBoneTransformsTo(transforms); + + foreach (var mesh in model.Meshes) + { + var meshParts = mesh.MeshParts; + foreach (var meshPart in meshParts) + { + var vertexBuffer = meshPart.VertexBuffer; + var declaration = vertexBuffer.VertexDeclaration; + var vertexSize = declaration.VertexStride / sizeof(float); + + var rawVertexBuffer = new float[vertexBuffer.VertexCount * vertexSize]; + vertexBuffer.GetData(rawVertexBuffer); + + for (var vertexIndex = 0; vertexIndex < rawVertexBuffer.Length; vertexIndex += vertexSize) + { + var transform = transforms[mesh.ParentBone.Index] * escala; + var vertex = new Vector3(rawVertexBuffer[vertexIndex], rawVertexBuffer[vertexIndex + 1], rawVertexBuffer[vertexIndex + 2]); + vertex = Vector3.Transform(vertex, transform); + minPoint = Vector3.Min(minPoint, vertex); + maxPoint = Vector3.Max(maxPoint, vertex); + } + } + } + + return new BoundingBox(minPoint + position, maxPoint + position); + } + + public static Vector3 GetCenter(BoundingBox box) + { + return (box.Max + box.Min) * 0.5f; + } + + public static Vector3 GetExtents(BoundingBox box) + { + var max = box.Max; + var min = box.Min; + + return (max - min) * 0.5f; + } + + } +} \ No newline at end of file diff --git a/TGC.MonoGame.TP/Collisions/OrientedBundingBox.cs b/TGC.MonoGame.TP/Collisions/OrientedBundingBox.cs new file mode 100644 index 000000000..b8088ed6d --- /dev/null +++ b/TGC.MonoGame.TP/Collisions/OrientedBundingBox.cs @@ -0,0 +1,280 @@ +using Microsoft.Xna.Framework; +using System; + +namespace ThunderingTanks.Collisions +{ + + public class OrientedBoundingBox + { + + public Vector3 Center { get; set; } + + public Matrix Orientation { get; set; } + + public Vector3 Extents { get; set; } + + public OrientedBoundingBox() { } + + public OrientedBoundingBox(Vector3 center, Vector3 extents) + { + Center = center; + Extents = extents; + Orientation = Matrix.Identity; + } + + public void Rotate(Matrix rotation) + { + Orientation = rotation; + } + + public void Rotate(Quaternion rotation) + { + Rotate(Matrix.CreateFromQuaternion(rotation)); + } + + public static OrientedBoundingBox ComputeFromPoints(Vector3[] points) + { + return ComputeFromPointsRecursive(points, Vector3.Zero, new Vector3(360, 360, 360), 10f); + } + + private static OrientedBoundingBox ComputeFromPointsRecursive(Vector3[] points, Vector3 initValues, Vector3 endValues, + float step) + { + var minObb = new OrientedBoundingBox(); + var minimumVolume = float.MaxValue; + var minInitValues = Vector3.Zero; + var minEndValues = Vector3.Zero; + var transformedPoints = new Vector3[points.Length]; + float y, z; + + var x = initValues.X; + while (x <= endValues.X) + { + y = initValues.Y; + var rotationX = MathHelper.ToRadians(x); + while (y <= endValues.Y) + { + z = initValues.Z; + var rotationY = MathHelper.ToRadians(y); + while (z <= endValues.Z) + { + var rotationZ = MathHelper.ToRadians(z); + var rotationMatrix = Matrix.CreateFromYawPitchRoll(rotationY, rotationX, rotationZ); + + for (var index = 0; index < transformedPoints.Length; index++) + transformedPoints[index] = Vector3.Transform(points[index], rotationMatrix); + + var aabb = BoundingBox.CreateFromPoints(transformedPoints); + + var volume = BoundingVolumesExtensions.GetVolume(aabb); + + if (volume < minimumVolume) + { + minimumVolume = volume; + minInitValues = new Vector3(x, y, z); + minEndValues = new Vector3(x + step, y + step, z + step); + + var center = BoundingVolumesExtensions.GetCenter(aabb); + center = Vector3.Transform(center, rotationMatrix); + + minObb = new OrientedBoundingBox(center, BoundingVolumesExtensions.GetExtents(aabb)); + minObb.Orientation = rotationMatrix; + } + + z += step; + } + y += step; + } + x += step; + } + + if (step > 0.01f) + minObb = ComputeFromPointsRecursive(points, minInitValues, minEndValues, step / 10f); + + return minObb; + } + public static OrientedBoundingBox FromAABB(BoundingBox box) + { + var center = BoundingVolumesExtensions.GetCenter(box); + var extents = BoundingVolumesExtensions.GetExtents(box); + return new OrientedBoundingBox(center, extents); + } + + public Vector3 ToOBBSpace(Vector3 point) + { + var difference = point - Center; + return Vector3.Transform(difference, Orientation); + } + + private float[] ToArray(Vector3 vector) + { + return new[] { vector.X, vector.Y, vector.Z }; + } + + private float[] ToFloatArray(Matrix matrix) + { + return new[] + { + matrix.M11, matrix.M21, matrix.M31, + matrix.M12, matrix.M22, matrix.M32, + matrix.M13, matrix.M23, matrix.M33, + }; + } + + public bool Intersects(OrientedBoundingBox box) + { + float ra; + float rb; + var R = new float[3, 3]; + var AbsR = new float[3, 3]; + var ae = ToArray(Extents); + var be = ToArray(box.Extents); + + var result = ToFloatArray(Matrix.Multiply(Orientation, box.Orientation)); + + for (var i = 0; i < 3; i++) + for (var j = 0; j < 3; j++) + R[i, j] = result[i * 3 + j]; + + var tVec = box.Center - Center; + + var t = ToArray(Vector3.Transform(tVec, Orientation)); + + for (var i = 0; i < 3; i++) + for (var j = 0; j < 3; j++) + AbsR[i, j] = MathF.Abs(R[i, j]) + float.Epsilon; + + for (var i = 0; i < 3; i++) + { + ra = ae[i]; + rb = be[0] * AbsR[i, 0] + be[1] * AbsR[i, 1] + be[2] * AbsR[i, 2]; + if (MathF.Abs(t[i]) > ra + rb) return false; + } + + for (var i = 0; i < 3; i++) + { + ra = ae[0] * AbsR[0, i] + ae[1] * AbsR[1, i] + ae[2] * AbsR[2, i]; + rb = be[i]; + if (MathF.Abs(t[0] * R[0, i] + t[1] * R[1, i] + t[2] * R[2, i]) > ra + rb) return false; + } + + ra = ae[1] * AbsR[2, 0] + ae[2] * AbsR[1, 0]; + rb = be[1] * AbsR[0, 2] + be[2] * AbsR[0, 1]; + if (MathF.Abs(t[2] * R[1, 0] - t[1] * R[2, 0]) > ra + rb) return false; + + ra = ae[1] * AbsR[2, 1] + ae[2] * AbsR[1, 1]; + rb = be[0] * AbsR[0, 2] + be[2] * AbsR[0, 0]; + if (MathF.Abs(t[2] * R[1, 1] - t[1] * R[2, 1]) > ra + rb) return false; + + ra = ae[1] * AbsR[2, 2] + ae[2] * AbsR[1, 2]; + rb = be[0] * AbsR[0, 1] + be[1] * AbsR[0, 0]; + if (MathF.Abs(t[2] * R[1, 2] - t[1] * R[2, 2]) > ra + rb) return false; + + ra = ae[0] * AbsR[2, 0] + ae[2] * AbsR[0, 0]; + rb = be[1] * AbsR[1, 2] + be[2] * AbsR[1, 1]; + if (MathF.Abs(t[0] * R[2, 0] - t[2] * R[0, 0]) > ra + rb) return false; + + ra = ae[0] * AbsR[2, 1] + ae[2] * AbsR[0, 1]; + rb = be[0] * AbsR[1, 2] + be[2] * AbsR[1, 0]; + if (MathF.Abs(t[0] * R[2, 1] - t[2] * R[0, 1]) > ra + rb) return false; + + ra = ae[0] * AbsR[2, 2] + ae[2] * AbsR[0, 2]; + rb = be[0] * AbsR[1, 1] + be[1] * AbsR[1, 0]; + if (MathF.Abs(t[0] * R[2, 2] - t[2] * R[0, 2]) > ra + rb) return false; + + ra = ae[0] * AbsR[1, 0] + ae[1] * AbsR[0, 0]; + rb = be[1] * AbsR[2, 2] + be[2] * AbsR[2, 1]; + if (MathF.Abs(t[1] * R[0, 0] - t[0] * R[1, 0]) > ra + rb) return false; + + ra = ae[0] * AbsR[1, 1] + ae[1] * AbsR[0, 1]; + rb = be[0] * AbsR[2, 2] + be[2] * AbsR[2, 0]; + if (MathF.Abs(t[1] * R[0, 1] - t[0] * R[1, 1]) > ra + rb) return false; + + ra = ae[0] * AbsR[1, 2] + ae[1] * AbsR[0, 2]; + rb = be[0] * AbsR[2, 1] + be[1] * AbsR[2, 0]; + if (MathF.Abs(t[1] * R[0, 2] - t[0] * R[1, 2]) > ra + rb) return false; + + return true; + } + + public bool Intersects(BoundingBox box) + { + return Intersects(FromAABB(box)); + } + + public bool Intersects(Ray ray, out float? result) + { + var rayOrigin = ray.Position; + var rayDestination = rayOrigin + ray.Direction; + + var rayOriginInOBBSpace = ToOBBSpace(rayOrigin); + var rayDestinationInOBBSpace = ToOBBSpace(rayDestination); + + var rayInOBBSpace = new Ray(rayOriginInOBBSpace, Vector3.Normalize(rayDestinationInOBBSpace - rayOriginInOBBSpace)); + + var enclosingBox = new BoundingBox(-Extents, Extents); + + var testResult = enclosingBox.Intersects(rayInOBBSpace); + result = testResult; + + return testResult != null; + } + + public bool Intersects(BoundingSphere sphere) + { + + var obbSpaceSphere = new BoundingSphere(ToOBBSpace(sphere.Center), sphere.Radius); + + var aabb = new BoundingBox(-Extents, Extents); + + return aabb.Intersects(obbSpaceSphere); + } + + public PlaneIntersectionType Intersects(Plane plane) + { + + var normal = Vector3.Transform(plane.Normal, Orientation); + + var r = MathF.Abs(Extents.X * normal.X) + + MathF.Abs(Extents.Y * normal.Y) + + MathF.Abs(Extents.Z * normal.Z); + + var d = Vector3.Dot(plane.Normal, Center) + plane.D; + + if (MathF.Abs(d) < r) + return PlaneIntersectionType.Intersecting; + else if (d < 0.0f) + return PlaneIntersectionType.Front; + else + return PlaneIntersectionType.Back; + } + + public bool Intersects(BoundingFrustum frustum) + { + var planes = new[] + { + frustum.Left, + frustum.Right, + frustum.Far, + frustum.Near, + frustum.Bottom, + frustum.Top + }; + + for (var faceIndex = 0; faceIndex < 6; ++faceIndex) + { + var side = Intersects(planes[faceIndex]); + if (side == PlaneIntersectionType.Back) + return false; + } + return true; + } + + public Vector3 ToWorldSpace(Vector3 point) + { + return Center + Vector3.Transform(point, Orientation); + } + + } + +} diff --git a/TGC.MonoGame.TP/Collisions/TGCCollisionUtils.cs b/TGC.MonoGame.TP/Collisions/TGCCollisionUtils.cs new file mode 100644 index 000000000..c51acb923 --- /dev/null +++ b/TGC.MonoGame.TP/Collisions/TGCCollisionUtils.cs @@ -0,0 +1,74 @@ +using Microsoft.Xna.Framework; + +namespace TGC.MonoGame.Samples.Collisions +{ + /// + /// Utilidades para hacer detección de colisiones + /// + public class TGCCollisionUtils + { + /// + /// Detecta colision entre un segmento pq y un triangulo abc. + /// Devuelve true si hay colision y carga las coordenadas barycentricas (u,v,w) de la colision, el + /// instante t de colision y el punto c de colision. + /// Basado en: Real Time Collision Detection pag 191 + /// + /// Inicio del segmento + /// Fin del segmento + /// Vertice 1 del triangulo + /// Vertice 2 del triangulo + /// Vertice 3 del triangulo + /// Coordenadas barycentricas de colision + /// Instante de colision + /// Punto de colision + /// True si hay colision + public static bool IntersectSegmentTriangle(Vector3 p, Vector3 q, Vector3 a, Vector3 b, Vector3 c, + out Vector3 uvw, out float t, out Vector3 col) + { + float u; + float v; + float w; + uvw = Vector3.Zero; + col = Vector3.Zero; + t = -1; + + var ab = b - a; + var ac = c - a; + var qp = p - q; + + // Compute triangle normal. Can be precalculated or cached if intersecting multiple segments against the same triangle + var n = Vector3.Cross(ab, ac); + + // Compute denominator d. If d <= 0, segment is parallel to or points away from triangle, so exit early + var d = Vector3.Dot(qp, n); + if (d <= 0.0f) return false; + + // Compute intersection t value of pq with plane of triangle. A ray intersects iff 0 <= t. + // Segment intersects iff 0 <= t <= 1. Delay dividing by d until intersection has been found to pierce triangle + var ap = p - a; + t = Vector3.Dot(ap, n); + if (t < 0.0f) return false; + if (t > d) return false; // For segment; exclude this code line for a ray test + + // Compute barycentric coordinate components and test if within bounds + var e = Vector3.Cross(qp, ap); + v = Vector3.Dot(ac, e); + if (v < 0.0f || v > d) return false; + w = -Vector3.Dot(ab, e); + if (w < 0.0f || v + w > d) return false; + + // Segment/ray intersects triangle. Perform delayed division and compute the last barycentric coordinate component + var ood = 1.0f / d; + t *= ood; + v *= ood; + w *= ood; + u = 1.0f - v - w; + + uvw.X = u; + uvw.Y = v; + uvw.Z = w; + col = p + t * (p - q); + return true; + } + } +} \ No newline at end of file diff --git a/TGC.MonoGame.TP/Content/3D/geometries/arrow.fbx b/TGC.MonoGame.TP/Content/3D/geometries/arrow.fbx new file mode 100644 index 000000000..a6eee3cb3 --- /dev/null +++ b/TGC.MonoGame.TP/Content/3D/geometries/arrow.fbx @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:190d36de9cb1e02cb60bfdf030f45cf9373a6b3014aeeb5b54d63ca4ffb01b99 +size 21932 diff --git a/TGC.MonoGame.TP/Content/Content.mgcb b/TGC.MonoGame.TP/Content/Content.mgcb index 0aac68293..daea976e6 100644 --- a/TGC.MonoGame.TP/Content/Content.mgcb +++ b/TGC.MonoGame.TP/Content/Content.mgcb @@ -13,13 +13,589 @@ #---------------------------------- Content ---------------------------------# +#begin 3D/geometries/arrow.fbx +/importer:FbxImporter +/processor:ModelProcessor +/processorParam:ColorKeyColor=0,0,0,0 +/processorParam:ColorKeyEnabled=True +/processorParam:DefaultEffect=BasicEffect +/processorParam:GenerateMipmaps=True +/processorParam:GenerateTangentFrames=False +/processorParam:PremultiplyTextureAlpha=True +/processorParam:PremultiplyVertexColors=True +/processorParam:ResizeTexturesToPowerOfTwo=False +/processorParam:RotationX=0 +/processorParam:RotationY=0 +/processorParam:RotationZ=0 +/processorParam:Scale=1 +/processorParam:SwapWindingOrder=False +/processorParam:TextureFormat=Compressed +/build:3D/geometries/arrow.fbx + #begin Effects/BasicShader.fx /importer:EffectImporter /processor:EffectProcessor /processorParam:DebugMode=Auto /build:Effects/BasicShader.fx -#begin Models/tgc-logo/tgc-logo.fbx +#begin Effects/Gizmos.fx +/importer:EffectImporter +/processor:EffectProcessor +/processorParam:DebugMode=Auto +/build:Effects/Gizmos.fx + +#begin Effects/Shadows.fx +/importer:EffectImporter +/processor:EffectProcessor +/processorParam:DebugMode=Auto +/build:Effects/Shadows.fx + +#begin Effects/SkyBox.fx +/importer:EffectImporter +/processor:EffectProcessor +/processorParam:DebugMode=Auto +/build:Effects/SkyBox.fx + +#begin Effects/TextureMerge.fx +/importer:EffectImporter +/processor:EffectProcessor +/processorParam:DebugMode=Auto +/build:Effects/TextureMerge.fx + +#begin Fonts/arial.spritefont +/importer:FontDescriptionImporter +/processor:FontDescriptionProcessor +/processorParam:PremultiplyAlpha=True +/processorParam:TextureFormat=Compressed +/build:Fonts/arial.spritefont + +#begin Fonts/warisover/WarIsOver.spritefont +/importer:FontDescriptionImporter +/processor:FontDescriptionProcessor +/processorParam:PremultiplyAlpha=True +/processorParam:TextureFormat=Compressed +/build:Fonts/warisover/WarIsOver.spritefont + +#begin Models/64Trees/firs_1.fbx +/importer:FbxImporter +/processor:ModelProcessor +/processorParam:ColorKeyColor=0,0,0,0 +/processorParam:ColorKeyEnabled=True +/processorParam:DefaultEffect=BasicEffect +/processorParam:GenerateMipmaps=True +/processorParam:GenerateTangentFrames=False +/processorParam:PremultiplyTextureAlpha=True +/processorParam:PremultiplyVertexColors=True +/processorParam:ResizeTexturesToPowerOfTwo=False +/processorParam:RotationX=0 +/processorParam:RotationY=0 +/processorParam:RotationZ=0 +/processorParam:Scale=1 +/processorParam:SwapWindingOrder=False +/processorParam:TextureFormat=NoChange +/build:Models/64Trees/firs_1.fbx + +#begin Models/64Trees/nature_bark_fir_01_l_0001_b.png +/importer:TextureImporter +/processor:TextureProcessor +/processorParam:ColorKeyColor=255,0,255,255 +/processorParam:ColorKeyEnabled=True +/processorParam:GenerateMipmaps=True +/processorParam:PremultiplyAlpha=True +/processorParam:ResizeToPowerOfTwo=False +/processorParam:MakeSquare=False +/processorParam:TextureFormat=Color +/build:Models/64Trees/nature_bark_fir_01_l_0001_b.png + +#begin Models/64Trees/nature_bark_fir_01_l_0001.jpg +/importer:TextureImporter +/processor:TextureProcessor +/processorParam:ColorKeyColor=255,0,255,255 +/processorParam:ColorKeyEnabled=True +/processorParam:GenerateMipmaps=True +/processorParam:PremultiplyAlpha=True +/processorParam:ResizeToPowerOfTwo=False +/processorParam:MakeSquare=False +/processorParam:TextureFormat=Color +/build:Models/64Trees/nature_bark_fir_01_l_0001.jpg + +#begin Models/assets militares/rsg_military_antitank_hedgehog_01.fbx +/importer:FbxImporter +/processor:ModelProcessor +/processorParam:ColorKeyColor=0,0,0,0 +/processorParam:ColorKeyEnabled=True +/processorParam:DefaultEffect=BasicEffect +/processorParam:GenerateMipmaps=True +/processorParam:GenerateTangentFrames=False +/processorParam:PremultiplyTextureAlpha=True +/processorParam:PremultiplyVertexColors=True +/processorParam:ResizeTexturesToPowerOfTwo=False +/processorParam:RotationX=0 +/processorParam:RotationY=0 +/processorParam:RotationZ=0 +/processorParam:Scale=1 +/processorParam:SwapWindingOrder=False +/processorParam:TextureFormat=Compressed +/build:Models/assets militares/rsg_military_antitank_hedgehog_01.fbx + +#begin Models/assets militares/rsg_military_barbed_wire_01.fbx +/importer:FbxImporter +/processor:ModelProcessor +/processorParam:ColorKeyColor=0,0,0,0 +/processorParam:ColorKeyEnabled=True +/processorParam:DefaultEffect=BasicEffect +/processorParam:GenerateMipmaps=True +/processorParam:GenerateTangentFrames=False +/processorParam:PremultiplyTextureAlpha=True +/processorParam:PremultiplyVertexColors=True +/processorParam:ResizeTexturesToPowerOfTwo=False +/processorParam:RotationX=0 +/processorParam:RotationY=0 +/processorParam:RotationZ=0 +/processorParam:Scale=1 +/processorParam:SwapWindingOrder=False +/processorParam:TextureFormat=Compressed +/build:Models/assets militares/rsg_military_barbed_wire_01.fbx + +#begin Models/assets militares/rsg_military_concret-block_01.fbx +/importer:FbxImporter +/processor:ModelProcessor +/processorParam:ColorKeyColor=0,0,0,0 +/processorParam:ColorKeyEnabled=True +/processorParam:DefaultEffect=BasicEffect +/processorParam:GenerateMipmaps=True +/processorParam:GenerateTangentFrames=False +/processorParam:PremultiplyTextureAlpha=True +/processorParam:PremultiplyVertexColors=True +/processorParam:ResizeTexturesToPowerOfTwo=False +/processorParam:RotationX=0 +/processorParam:RotationY=0 +/processorParam:RotationZ=0 +/processorParam:Scale=1 +/processorParam:SwapWindingOrder=False +/processorParam:TextureFormat=Compressed +/build:Models/assets militares/rsg_military_concret-block_01.fbx + +#begin Models/assets militares/rsg_military_sandbox_01.fbx +/importer:FbxImporter +/processor:ModelProcessor +/processorParam:ColorKeyColor=0,0,0,0 +/processorParam:ColorKeyEnabled=True +/processorParam:DefaultEffect=BasicEffect +/processorParam:GenerateMipmaps=True +/processorParam:GenerateTangentFrames=False +/processorParam:PremultiplyTextureAlpha=True +/processorParam:PremultiplyVertexColors=True +/processorParam:ResizeTexturesToPowerOfTwo=False +/processorParam:RotationX=0 +/processorParam:RotationY=0 +/processorParam:RotationZ=0 +/processorParam:Scale=1 +/processorParam:SwapWindingOrder=False +/processorParam:TextureFormat=Compressed +/build:Models/assets militares/rsg_military_sandbox_01.fbx + +#begin Models/assets militares/Textures/UE/T_rsg_military_antitank_hedgehog_01_AOR.tga +/importer:TextureImporter +/processor:TextureProcessor +/processorParam:ColorKeyColor=255,0,255,255 +/processorParam:ColorKeyEnabled=True +/processorParam:GenerateMipmaps=False +/processorParam:PremultiplyAlpha=True +/processorParam:ResizeToPowerOfTwo=False +/processorParam:MakeSquare=False +/processorParam:TextureFormat=Color +/build:Models/assets militares/Textures/UE/T_rsg_military_antitank_hedgehog_01_AOR.tga + +#begin Models/assets militares/Textures/UE/T_rsg_military_antitank_hedgehog_01_BC.tga +/importer:TextureImporter +/processor:TextureProcessor +/processorParam:ColorKeyColor=255,0,255,255 +/processorParam:ColorKeyEnabled=True +/processorParam:GenerateMipmaps=False +/processorParam:PremultiplyAlpha=True +/processorParam:ResizeToPowerOfTwo=False +/processorParam:MakeSquare=False +/processorParam:TextureFormat=Color +/build:Models/assets militares/Textures/UE/T_rsg_military_antitank_hedgehog_01_BC.tga + +#begin Models/assets militares/Textures/UE/T_rsg_military_antitank_hedgehog_01_N.tga +/importer:TextureImporter +/processor:TextureProcessor +/processorParam:ColorKeyColor=255,0,255,255 +/processorParam:ColorKeyEnabled=True +/processorParam:GenerateMipmaps=False +/processorParam:PremultiplyAlpha=True +/processorParam:ResizeToPowerOfTwo=False +/processorParam:MakeSquare=False +/processorParam:TextureFormat=Color +/build:Models/assets militares/Textures/UE/T_rsg_military_antitank_hedgehog_01_N.tga + +#begin Models/assets militares/Textures/UE/T_rsg_military_concret_block_01_AOR.tga +/importer:TextureImporter +/processor:TextureProcessor +/processorParam:ColorKeyColor=255,0,255,255 +/processorParam:ColorKeyEnabled=True +/processorParam:GenerateMipmaps=False +/processorParam:PremultiplyAlpha=True +/processorParam:ResizeToPowerOfTwo=False +/processorParam:MakeSquare=False +/processorParam:TextureFormat=Color +/build:Models/assets militares/Textures/UE/T_rsg_military_concret_block_01_AOR.tga + +#begin Models/assets militares/Textures/UE/T_rsg_military_concret_block_01_BC.tga +/importer:TextureImporter +/processor:TextureProcessor +/processorParam:ColorKeyColor=255,0,255,255 +/processorParam:ColorKeyEnabled=True +/processorParam:GenerateMipmaps=False +/processorParam:PremultiplyAlpha=True +/processorParam:ResizeToPowerOfTwo=False +/processorParam:MakeSquare=False +/processorParam:TextureFormat=Color +/build:Models/assets militares/Textures/UE/T_rsg_military_concret_block_01_BC.tga + +#begin Models/assets militares/Textures/UE/T_rsg_military_concret_block_01_N.tga +/importer:TextureImporter +/processor:TextureProcessor +/processorParam:ColorKeyColor=255,0,255,255 +/processorParam:ColorKeyEnabled=True +/processorParam:GenerateMipmaps=False +/processorParam:PremultiplyAlpha=True +/processorParam:ResizeToPowerOfTwo=False +/processorParam:MakeSquare=False +/processorParam:TextureFormat=Color +/build:Models/assets militares/Textures/UE/T_rsg_military_concret_block_01_N.tga + +#begin Models/assets militares/Textures/UE/T_rsg_military_sandbox_01_AOR.tga +/importer:TextureImporter +/processor:TextureProcessor +/processorParam:ColorKeyColor=255,0,255,255 +/processorParam:ColorKeyEnabled=True +/processorParam:GenerateMipmaps=False +/processorParam:PremultiplyAlpha=True +/processorParam:ResizeToPowerOfTwo=False +/processorParam:MakeSquare=False +/processorParam:TextureFormat=Color +/build:Models/assets militares/Textures/UE/T_rsg_military_sandbox_01_AOR.tga + +#begin Models/assets militares/Textures/UE/T_rsg_military_sandbox_01_BC.tga +/importer:TextureImporter +/processor:TextureProcessor +/processorParam:ColorKeyColor=255,0,255,255 +/processorParam:ColorKeyEnabled=True +/processorParam:GenerateMipmaps=False +/processorParam:PremultiplyAlpha=True +/processorParam:ResizeToPowerOfTwo=False +/processorParam:MakeSquare=False +/processorParam:TextureFormat=Color +/build:Models/assets militares/Textures/UE/T_rsg_military_sandbox_01_BC.tga + +#begin Models/assets militares/Textures/UE/T_rsg_military_sandbox_01_N.tga +/importer:TextureImporter +/processor:TextureProcessor +/processorParam:ColorKeyColor=255,0,255,255 +/processorParam:ColorKeyEnabled=True +/processorParam:GenerateMipmaps=False +/processorParam:PremultiplyAlpha=True +/processorParam:ResizeToPowerOfTwo=False +/processorParam:MakeSquare=False +/processorParam:TextureFormat=Color +/build:Models/assets militares/Textures/UE/T_rsg_military_sandbox_01_N.tga + +#begin Models/assets militares/Textures/Unity/T_rsg_military_antitank_hedgehog_01_AOR.tga +/importer:TextureImporter +/processor:TextureProcessor +/processorParam:ColorKeyColor=255,0,255,255 +/processorParam:ColorKeyEnabled=True +/processorParam:GenerateMipmaps=False +/processorParam:PremultiplyAlpha=True +/processorParam:ResizeToPowerOfTwo=False +/processorParam:MakeSquare=False +/processorParam:TextureFormat=Color +/build:Models/assets militares/Textures/Unity/T_rsg_military_antitank_hedgehog_01_AOR.tga + +#begin Models/assets militares/Textures/Unity/T_rsg_military_antitank_hedgehog_01_BC.tga +/importer:TextureImporter +/processor:TextureProcessor +/processorParam:ColorKeyColor=255,0,255,255 +/processorParam:ColorKeyEnabled=True +/processorParam:GenerateMipmaps=False +/processorParam:PremultiplyAlpha=True +/processorParam:ResizeToPowerOfTwo=False +/processorParam:MakeSquare=False +/processorParam:TextureFormat=Color +/build:Models/assets militares/Textures/Unity/T_rsg_military_antitank_hedgehog_01_BC.tga + +#begin Models/assets militares/Textures/Unity/T_rsg_military_antitank_hedgehog_01_N.tga +/importer:TextureImporter +/processor:TextureProcessor +/processorParam:ColorKeyColor=255,0,255,255 +/processorParam:ColorKeyEnabled=True +/processorParam:GenerateMipmaps=False +/processorParam:PremultiplyAlpha=True +/processorParam:ResizeToPowerOfTwo=False +/processorParam:MakeSquare=False +/processorParam:TextureFormat=Color +/build:Models/assets militares/Textures/Unity/T_rsg_military_antitank_hedgehog_01_N.tga + +#begin Models/assets militares/Textures/Unity/T_rsg_military_concret_block_01_AOR.tga +/importer:TextureImporter +/processor:TextureProcessor +/processorParam:ColorKeyColor=255,0,255,255 +/processorParam:ColorKeyEnabled=True +/processorParam:GenerateMipmaps=False +/processorParam:PremultiplyAlpha=True +/processorParam:ResizeToPowerOfTwo=False +/processorParam:MakeSquare=False +/processorParam:TextureFormat=Color +/build:Models/assets militares/Textures/Unity/T_rsg_military_concret_block_01_AOR.tga + +#begin Models/assets militares/Textures/Unity/T_rsg_military_concret_block_01_BC.tga +/importer:TextureImporter +/processor:TextureProcessor +/processorParam:ColorKeyColor=255,0,255,255 +/processorParam:ColorKeyEnabled=True +/processorParam:GenerateMipmaps=False +/processorParam:PremultiplyAlpha=True +/processorParam:ResizeToPowerOfTwo=False +/processorParam:MakeSquare=False +/processorParam:TextureFormat=Color +/build:Models/assets militares/Textures/Unity/T_rsg_military_concret_block_01_BC.tga + +#begin Models/assets militares/Textures/Unity/T_rsg_military_concret_block_01_N.tga +/importer:TextureImporter +/processor:TextureProcessor +/processorParam:ColorKeyColor=255,0,255,255 +/processorParam:ColorKeyEnabled=True +/processorParam:GenerateMipmaps=False +/processorParam:PremultiplyAlpha=True +/processorParam:ResizeToPowerOfTwo=False +/processorParam:MakeSquare=False +/processorParam:TextureFormat=Color +/build:Models/assets militares/Textures/Unity/T_rsg_military_concret_block_01_N.tga + +#begin Models/assets militares/Textures/Unity/T_rsg_military_sandbox_01_AOR.tga +/importer:TextureImporter +/processor:TextureProcessor +/processorParam:ColorKeyColor=255,0,255,255 +/processorParam:ColorKeyEnabled=True +/processorParam:GenerateMipmaps=False +/processorParam:PremultiplyAlpha=True +/processorParam:ResizeToPowerOfTwo=False +/processorParam:MakeSquare=False +/processorParam:TextureFormat=Color +/build:Models/assets militares/Textures/Unity/T_rsg_military_sandbox_01_AOR.tga + +#begin Models/assets militares/Textures/Unity/T_rsg_military_sandbox_01_BC.tga +/importer:TextureImporter +/processor:TextureProcessor +/processorParam:ColorKeyColor=255,0,255,255 +/processorParam:ColorKeyEnabled=True +/processorParam:GenerateMipmaps=False +/processorParam:PremultiplyAlpha=True +/processorParam:ResizeToPowerOfTwo=False +/processorParam:MakeSquare=False +/processorParam:TextureFormat=Color +/build:Models/assets militares/Textures/Unity/T_rsg_military_sandbox_01_BC.tga + +#begin Models/assets militares/Textures/Unity/T_rsg_military_sandbox_01_N.tga +/importer:TextureImporter +/processor:TextureProcessor +/processorParam:ColorKeyColor=255,0,255,255 +/processorParam:ColorKeyEnabled=True +/processorParam:GenerateMipmaps=False +/processorParam:PremultiplyAlpha=True +/processorParam:ResizeToPowerOfTwo=False +/processorParam:MakeSquare=False +/processorParam:TextureFormat=Color +/build:Models/assets militares/Textures/Unity/T_rsg_military_sandbox_01_N.tga + +#begin Models/casa/house.fbx +/importer:FbxImporter +/processor:ModelProcessor +/processorParam:ColorKeyColor=0,0,0,0 +/processorParam:ColorKeyEnabled=True +/processorParam:DefaultEffect=BasicEffect +/processorParam:GenerateMipmaps=True +/processorParam:GenerateTangentFrames=False +/processorParam:PremultiplyTextureAlpha=True +/processorParam:PremultiplyVertexColors=True +/processorParam:ResizeTexturesToPowerOfTwo=False +/processorParam:RotationX=0 +/processorParam:RotationY=0 +/processorParam:RotationZ=0 +/processorParam:Scale=1 +/processorParam:SwapWindingOrder=False +/processorParam:TextureFormat=Compressed +/build:Models/casa/house.fbx + +#begin Models/cube.fbx +/importer:FbxImporter +/processor:ModelProcessor +/processorParam:ColorKeyColor=0,0,0,0 +/processorParam:ColorKeyEnabled=True +/processorParam:DefaultEffect=BasicEffect +/processorParam:GenerateMipmaps=True +/processorParam:GenerateTangentFrames=False +/processorParam:PremultiplyTextureAlpha=True +/processorParam:PremultiplyVertexColors=True +/processorParam:ResizeTexturesToPowerOfTwo=False +/processorParam:RotationX=0 +/processorParam:RotationY=0 +/processorParam:RotationZ=0 +/processorParam:Scale=1 +/processorParam:SwapWindingOrder=False +/processorParam:TextureFormat=Compressed +/build:Models/cube.fbx + +#begin Models/GermanModel/Eye_albedo.jpeg +/importer:TextureImporter +/processor:TextureProcessor +/processorParam:ColorKeyColor=255,0,255,255 +/processorParam:ColorKeyEnabled=True +/processorParam:GenerateMipmaps=False +/processorParam:PremultiplyAlpha=True +/processorParam:ResizeToPowerOfTwo=False +/processorParam:MakeSquare=False +/processorParam:TextureFormat=Color +/build:Models/GermanModel/Eye_albedo.jpeg + +#begin Models/GermanModel/Eye_AO.jpeg +/importer:TextureImporter +/processor:TextureProcessor +/processorParam:ColorKeyColor=255,0,255,255 +/processorParam:ColorKeyEnabled=True +/processorParam:GenerateMipmaps=False +/processorParam:PremultiplyAlpha=True +/processorParam:ResizeToPowerOfTwo=False +/processorParam:MakeSquare=False +/processorParam:TextureFormat=Color +/build:Models/GermanModel/Eye_AO.jpeg + +#begin Models/GermanModel/Eye_metallic.jpeg +/importer:TextureImporter +/processor:TextureProcessor +/processorParam:ColorKeyColor=255,0,255,255 +/processorParam:ColorKeyEnabled=True +/processorParam:GenerateMipmaps=False +/processorParam:PremultiplyAlpha=True +/processorParam:ResizeToPowerOfTwo=False +/processorParam:MakeSquare=False +/processorParam:TextureFormat=Color +/build:Models/GermanModel/Eye_metallic.jpeg + +#begin Models/GermanModel/Eye_normal.jpeg +/importer:TextureImporter +/processor:TextureProcessor +/processorParam:ColorKeyColor=255,0,255,255 +/processorParam:ColorKeyEnabled=True +/processorParam:GenerateMipmaps=False +/processorParam:PremultiplyAlpha=True +/processorParam:ResizeToPowerOfTwo=False +/processorParam:MakeSquare=False +/processorParam:TextureFormat=Color +/build:Models/GermanModel/Eye_normal.jpeg + +#begin Models/GermanModel/Gear_albedo.jpeg +/importer:TextureImporter +/processor:TextureProcessor +/processorParam:ColorKeyColor=255,0,255,255 +/processorParam:ColorKeyEnabled=True +/processorParam:GenerateMipmaps=False +/processorParam:PremultiplyAlpha=True +/processorParam:ResizeToPowerOfTwo=False +/processorParam:MakeSquare=False +/processorParam:TextureFormat=Color +/build:Models/GermanModel/Gear_albedo.jpeg + +#begin Models/GermanModel/Gear_AO.jpeg +/importer:TextureImporter +/processor:TextureProcessor +/processorParam:ColorKeyColor=255,0,255,255 +/processorParam:ColorKeyEnabled=True +/processorParam:GenerateMipmaps=False +/processorParam:PremultiplyAlpha=True +/processorParam:ResizeToPowerOfTwo=False +/processorParam:MakeSquare=False +/processorParam:TextureFormat=Color +/build:Models/GermanModel/Gear_AO.jpeg + +#begin Models/GermanModel/Gear_metallic.jpeg +/importer:TextureImporter +/processor:TextureProcessor +/processorParam:ColorKeyColor=255,0,255,255 +/processorParam:ColorKeyEnabled=True +/processorParam:GenerateMipmaps=False +/processorParam:PremultiplyAlpha=True +/processorParam:ResizeToPowerOfTwo=False +/processorParam:MakeSquare=False +/processorParam:TextureFormat=Color +/build:Models/GermanModel/Gear_metallic.jpeg + +#begin Models/GermanModel/Gear_normal.jpeg +/importer:TextureImporter +/processor:TextureProcessor +/processorParam:ColorKeyColor=255,0,255,255 +/processorParam:ColorKeyEnabled=True +/processorParam:GenerateMipmaps=False +/processorParam:PremultiplyAlpha=True +/processorParam:ResizeToPowerOfTwo=False +/processorParam:MakeSquare=False +/processorParam:TextureFormat=Color +/build:Models/GermanModel/Gear_normal.jpeg + +#begin Models/GermanModel/Gear_roughness.jpeg +/importer:TextureImporter +/processor:TextureProcessor +/processorParam:ColorKeyColor=255,0,255,255 +/processorParam:ColorKeyEnabled=True +/processorParam:GenerateMipmaps=False +/processorParam:PremultiplyAlpha=True +/processorParam:ResizeToPowerOfTwo=False +/processorParam:MakeSquare=False +/processorParam:TextureFormat=Color +/build:Models/GermanModel/Gear_roughness.jpeg + +#begin Models/GermanModel/GermanSoldier_1.fbx +/importer:FbxImporter +/processor:ModelProcessor +/processorParam:ColorKeyColor=0,0,0,0 +/processorParam:ColorKeyEnabled=True +/processorParam:DefaultEffect=BasicEffect +/processorParam:GenerateMipmaps=True +/processorParam:GenerateTangentFrames=False +/processorParam:PremultiplyTextureAlpha=True +/processorParam:PremultiplyVertexColors=True +/processorParam:ResizeTexturesToPowerOfTwo=False +/processorParam:RotationX=0 +/processorParam:RotationY=0 +/processorParam:RotationZ=0 +/processorParam:Scale=1 +/processorParam:SwapWindingOrder=True +/processorParam:TextureFormat=Compressed +/build:Models/GermanModel/GermanSoldier_1.fbx + +#begin Models/GermanModel/GermanSoldier_2.fbx +/importer:FbxImporter +/processor:ModelProcessor +/processorParam:ColorKeyColor=0,0,0,0 +/processorParam:ColorKeyEnabled=True +/processorParam:DefaultEffect=BasicEffect +/processorParam:GenerateMipmaps=True +/processorParam:GenerateTangentFrames=False +/processorParam:PremultiplyTextureAlpha=True +/processorParam:PremultiplyVertexColors=True +/processorParam:ResizeTexturesToPowerOfTwo=False +/processorParam:RotationX=0 +/processorParam:RotationY=0 +/processorParam:RotationZ=0 +/processorParam:Scale=1 +/processorParam:SwapWindingOrder=False +/processorParam:TextureFormat=Compressed +/build:Models/GermanModel/GermanSoldier_2.fbx + +#begin Models/GermanModel/GermanSoldier.fbx /importer:FbxImporter /processor:ModelProcessor /processorParam:ColorKeyColor=0,0,0,0 @@ -36,5 +612,1588 @@ /processorParam:Scale=1 /processorParam:SwapWindingOrder=False /processorParam:TextureFormat=Compressed -/build:Models/tgc-logo/tgc-logo.fbx +/build:Models/GermanModel/GermanSoldier.fbx + +#begin Models/GermanModel/Skin_albedo.jpeg +/importer:TextureImporter +/processor:TextureProcessor +/processorParam:ColorKeyColor=255,0,255,255 +/processorParam:ColorKeyEnabled=True +/processorParam:GenerateMipmaps=False +/processorParam:PremultiplyAlpha=True +/processorParam:ResizeToPowerOfTwo=False +/processorParam:MakeSquare=False +/processorParam:TextureFormat=Color +/build:Models/GermanModel/Skin_albedo.jpeg + +#begin Models/GermanModel/Skin_AO.jpeg +/importer:TextureImporter +/processor:TextureProcessor +/processorParam:ColorKeyColor=255,0,255,255 +/processorParam:ColorKeyEnabled=True +/processorParam:GenerateMipmaps=False +/processorParam:PremultiplyAlpha=True +/processorParam:ResizeToPowerOfTwo=False +/processorParam:MakeSquare=False +/processorParam:TextureFormat=Color +/build:Models/GermanModel/Skin_AO.jpeg + +#begin Models/GermanModel/Skin_metallic.jpeg +/importer:TextureImporter +/processor:TextureProcessor +/processorParam:ColorKeyColor=255,0,255,255 +/processorParam:ColorKeyEnabled=True +/processorParam:GenerateMipmaps=False +/processorParam:PremultiplyAlpha=True +/processorParam:ResizeToPowerOfTwo=False +/processorParam:MakeSquare=False +/processorParam:TextureFormat=Color +/build:Models/GermanModel/Skin_metallic.jpeg + +#begin Models/GermanModel/Skin_normal.jpeg +/importer:TextureImporter +/processor:TextureProcessor +/processorParam:ColorKeyColor=255,0,255,255 +/processorParam:ColorKeyEnabled=True +/processorParam:GenerateMipmaps=False +/processorParam:PremultiplyAlpha=True +/processorParam:ResizeToPowerOfTwo=False +/processorParam:MakeSquare=False +/processorParam:TextureFormat=Color +/build:Models/GermanModel/Skin_normal.jpeg + +#begin Models/GermanModel/Skin_roughness.jpeg +/importer:TextureImporter +/processor:TextureProcessor +/processorParam:ColorKeyColor=255,0,255,255 +/processorParam:ColorKeyEnabled=True +/processorParam:GenerateMipmaps=False +/processorParam:PremultiplyAlpha=True +/processorParam:ResizeToPowerOfTwo=False +/processorParam:MakeSquare=False +/processorParam:TextureFormat=Color +/build:Models/GermanModel/Skin_roughness.jpeg + +#begin Models/GermanModel/Wermarcht_albedo.jpeg +/importer:TextureImporter +/processor:TextureProcessor +/processorParam:ColorKeyColor=255,0,255,255 +/processorParam:ColorKeyEnabled=True +/processorParam:GenerateMipmaps=False +/processorParam:PremultiplyAlpha=True +/processorParam:ResizeToPowerOfTwo=False +/processorParam:MakeSquare=False +/processorParam:TextureFormat=Color +/build:Models/GermanModel/Wermarcht_albedo.jpeg + +#begin Models/GermanModel/Wermarcht_AO.jpeg +/importer:TextureImporter +/processor:TextureProcessor +/processorParam:ColorKeyColor=255,0,255,255 +/processorParam:ColorKeyEnabled=True +/processorParam:GenerateMipmaps=False +/processorParam:PremultiplyAlpha=True +/processorParam:ResizeToPowerOfTwo=False +/processorParam:MakeSquare=False +/processorParam:TextureFormat=Color +/build:Models/GermanModel/Wermarcht_AO.jpeg + +#begin Models/GermanModel/Wermarcht_metallic.jpeg +/importer:TextureImporter +/processor:TextureProcessor +/processorParam:ColorKeyColor=255,0,255,255 +/processorParam:ColorKeyEnabled=True +/processorParam:GenerateMipmaps=False +/processorParam:PremultiplyAlpha=True +/processorParam:ResizeToPowerOfTwo=False +/processorParam:MakeSquare=False +/processorParam:TextureFormat=Color +/build:Models/GermanModel/Wermarcht_metallic.jpeg + +#begin Models/GermanModel/Wermarcht_normal.jpeg +/importer:TextureImporter +/processor:TextureProcessor +/processorParam:ColorKeyColor=255,0,255,255 +/processorParam:ColorKeyEnabled=True +/processorParam:GenerateMipmaps=False +/processorParam:PremultiplyAlpha=True +/processorParam:ResizeToPowerOfTwo=False +/processorParam:MakeSquare=False +/processorParam:TextureFormat=Color +/build:Models/GermanModel/Wermarcht_normal.jpeg + +#begin Models/GermanModel/Wermarcht_roughness.jpeg +/importer:TextureImporter +/processor:TextureProcessor +/processorParam:ColorKeyColor=255,0,255,255 +/processorParam:ColorKeyEnabled=True +/processorParam:GenerateMipmaps=False +/processorParam:PremultiplyAlpha=True +/processorParam:ResizeToPowerOfTwo=False +/processorParam:MakeSquare=False +/processorParam:TextureFormat=Color +/build:Models/GermanModel/Wermarcht_roughness.jpeg + +#begin Models/grass/grassAlphaMapped.png +/importer:TextureImporter +/processor:TextureProcessor +/processorParam:ColorKeyColor=255,0,255,255 +/processorParam:ColorKeyEnabled=True +/processorParam:GenerateMipmaps=True +/processorParam:PremultiplyAlpha=True +/processorParam:ResizeToPowerOfTwo=False +/processorParam:MakeSquare=False +/processorParam:TextureFormat=Color +/build:Models/grass/grassAlphaMapped.png + +#begin Models/grass/grasscolor.png +/importer:TextureImporter +/processor:TextureProcessor +/processorParam:ColorKeyColor=255,0,255,255 +/processorParam:ColorKeyEnabled=True +/processorParam:GenerateMipmaps=True +/processorParam:PremultiplyAlpha=True +/processorParam:ResizeToPowerOfTwo=False +/processorParam:MakeSquare=False +/processorParam:TextureFormat=Color +/build:Models/grass/grasscolor.png + +#begin Models/grass/grassNormal.png +/importer:TextureImporter +/processor:TextureProcessor +/processorParam:ColorKeyColor=255,0,255,255 +/processorParam:ColorKeyEnabled=True +/processorParam:GenerateMipmaps=True +/processorParam:PremultiplyAlpha=True +/processorParam:ResizeToPowerOfTwo=False +/processorParam:MakeSquare=False +/processorParam:TextureFormat=Color +/build:Models/grass/grassNormal.png + +#begin Models/grass/grasspatches.fbx +/importer:FbxImporter +/processor:ModelProcessor +/processorParam:ColorKeyColor=0,0,0,0 +/processorParam:ColorKeyEnabled=True +/processorParam:DefaultEffect=BasicEffect +/processorParam:GenerateMipmaps=True +/processorParam:GenerateTangentFrames=False +/processorParam:PremultiplyTextureAlpha=True +/processorParam:PremultiplyVertexColors=True +/processorParam:ResizeTexturesToPowerOfTwo=False +/processorParam:RotationX=0 +/processorParam:RotationY=0 +/processorParam:RotationZ=0 +/processorParam:Scale=1 +/processorParam:SwapWindingOrder=False +/processorParam:TextureFormat=Compressed +/build:Models/grass/grasspatches.fbx + +#begin Models/grass/grassSmoothness.png +/importer:TextureImporter +/processor:TextureProcessor +/processorParam:ColorKeyColor=255,0,255,255 +/processorParam:ColorKeyEnabled=True +/processorParam:GenerateMipmaps=True +/processorParam:PremultiplyAlpha=True +/processorParam:ResizeToPowerOfTwo=False +/processorParam:MakeSquare=False +/processorParam:TextureFormat=Color +/build:Models/grass/grassSmoothness.png + +#begin Models/Grid/ground.x +/importer:XImporter +/processor:ModelProcessor +/processorParam:ColorKeyColor=0,0,0,0 +/processorParam:ColorKeyEnabled=True +/processorParam:DefaultEffect=BasicEffect +/processorParam:GenerateMipmaps=True +/processorParam:GenerateTangentFrames=False +/processorParam:PremultiplyTextureAlpha=True +/processorParam:PremultiplyVertexColors=True +/processorParam:ResizeTexturesToPowerOfTwo=False +/processorParam:RotationX=0 +/processorParam:RotationY=0 +/processorParam:RotationZ=0 +/processorParam:Scale=1 +/processorParam:SwapWindingOrder=False +/processorParam:TextureFormat=Compressed +/build:Models/Grid/ground.x + +#begin Models/Grid/terreno.png +/importer:TextureImporter +/processor:TextureProcessor +/processorParam:ColorKeyColor=255,0,255,255 +/processorParam:ColorKeyEnabled=True +/processorParam:GenerateMipmaps=False +/processorParam:PremultiplyAlpha=True +/processorParam:ResizeToPowerOfTwo=False +/processorParam:MakeSquare=False +/processorParam:TextureFormat=Color +/build:Models/Grid/terreno.png + +#begin Models/M4/Grant_track_NM.dds +/importer:TextureImporter +/processor:TextureProcessor +/processorParam:ColorKeyColor=255,0,255,255 +/processorParam:ColorKeyEnabled=True +/processorParam:GenerateMipmaps=True +/processorParam:PremultiplyAlpha=True +/processorParam:ResizeToPowerOfTwo=False +/processorParam:MakeSquare=False +/processorParam:TextureFormat=Color +/build:Models/M4/Grant_track_NM.dds + +#begin Models/M4/Grant_track_SM.dds +/importer:TextureImporter +/processor:TextureProcessor +/processorParam:ColorKeyColor=255,0,255,255 +/processorParam:ColorKeyEnabled=True +/processorParam:GenerateMipmaps=True +/processorParam:PremultiplyAlpha=True +/processorParam:ResizeToPowerOfTwo=False +/processorParam:MakeSquare=False +/processorParam:TextureFormat=Color +/build:Models/M4/Grant_track_SM.dds + +#begin Models/M4/Grant_track.dds +/importer:TextureImporter +/processor:TextureProcessor +/processorParam:ColorKeyColor=255,0,255,255 +/processorParam:ColorKeyEnabled=True +/processorParam:GenerateMipmaps=True +/processorParam:PremultiplyAlpha=True +/processorParam:ResizeToPowerOfTwo=False +/processorParam:MakeSquare=False +/processorParam:TextureFormat=Color +/build:Models/M4/Grant_track.dds + +#begin Models/M4/M4_Sherman_NM.dds +/importer:TextureImporter +/processor:TextureProcessor +/processorParam:ColorKeyColor=255,0,255,255 +/processorParam:ColorKeyEnabled=True +/processorParam:GenerateMipmaps=False +/processorParam:PremultiplyAlpha=True +/processorParam:ResizeToPowerOfTwo=False +/processorParam:MakeSquare=False +/processorParam:TextureFormat=Color +/build:Models/M4/M4_Sherman_NM.dds + +#begin Models/M4/M4_Sherman_SM.dds +/importer:TextureImporter +/processor:TextureProcessor +/processorParam:ColorKeyColor=255,0,255,255 +/processorParam:ColorKeyEnabled=True +/processorParam:GenerateMipmaps=False +/processorParam:PremultiplyAlpha=True +/processorParam:ResizeToPowerOfTwo=False +/processorParam:MakeSquare=False +/processorParam:TextureFormat=Color +/build:Models/M4/M4_Sherman_SM.dds + +#begin Models/M4/M4_Sherman.dds +/importer:TextureImporter +/processor:TextureProcessor +/processorParam:ColorKeyColor=255,0,255,255 +/processorParam:ColorKeyEnabled=True +/processorParam:GenerateMipmaps=True +/processorParam:PremultiplyAlpha=True +/processorParam:ResizeToPowerOfTwo=False +/processorParam:MakeSquare=False +/processorParam:TextureFormat=Color +/build:Models/M4/M4_Sherman.dds + +#begin Models/M4/M4.fbx +/importer:FbxImporter +/processor:ModelProcessor +/processorParam:ColorKeyColor=0,0,0,0 +/processorParam:ColorKeyEnabled=True +/processorParam:DefaultEffect=BasicEffect +/processorParam:GenerateMipmaps=True +/processorParam:GenerateTangentFrames=False +/processorParam:PremultiplyTextureAlpha=True +/processorParam:PremultiplyVertexColors=True +/processorParam:ResizeTexturesToPowerOfTwo=False +/processorParam:RotationX=0 +/processorParam:RotationY=0 +/processorParam:RotationZ=0 +/processorParam:Scale=1 +/processorParam:SwapWindingOrder=False +/processorParam:TextureFormat=Compressed +/build:Models/M4/M4.fbx + +#begin Models/ModelosVarios/MolinoProp/MolinoProp.fbx +/importer:FbxImporter +/processor:ModelProcessor +/processorParam:ColorKeyColor=0,0,0,0 +/processorParam:ColorKeyEnabled=True +/processorParam:DefaultEffect=BasicEffect +/processorParam:GenerateMipmaps=True +/processorParam:GenerateTangentFrames=False +/processorParam:PremultiplyTextureAlpha=True +/processorParam:PremultiplyVertexColors=True +/processorParam:ResizeTexturesToPowerOfTwo=False +/processorParam:RotationX=0 +/processorParam:RotationY=0 +/processorParam:RotationZ=0 +/processorParam:Scale=1 +/processorParam:SwapWindingOrder=False +/processorParam:TextureFormat=Compressed +/build:Models/ModelosVarios/MolinoProp/MolinoProp.fbx + +#begin Models/ModelosVarios/MolinoProp/T_AmericanPostBox_D.png +/importer:TextureImporter +/processor:TextureProcessor +/processorParam:ColorKeyColor=255,0,255,255 +/processorParam:ColorKeyEnabled=True +/processorParam:GenerateMipmaps=False +/processorParam:PremultiplyAlpha=True +/processorParam:ResizeToPowerOfTwo=False +/processorParam:MakeSquare=False +/processorParam:TextureFormat=Color +/build:Models/ModelosVarios/MolinoProp/T_AmericanPostBox_D.png + +#begin Models/ModelosVarios/MolinoProp/T_BMX_D.png +/importer:TextureImporter +/processor:TextureProcessor +/processorParam:ColorKeyColor=255,0,255,255 +/processorParam:ColorKeyEnabled=True +/processorParam:GenerateMipmaps=False +/processorParam:PremultiplyAlpha=True +/processorParam:ResizeToPowerOfTwo=False +/processorParam:MakeSquare=False +/processorParam:TextureFormat=Color +/build:Models/ModelosVarios/MolinoProp/T_BMX_D.png + +#begin Models/ModelosVarios/MolinoProp/T_BMX_O.png +/importer:TextureImporter +/processor:TextureProcessor +/processorParam:ColorKeyColor=255,0,255,255 +/processorParam:ColorKeyEnabled=True +/processorParam:GenerateMipmaps=False +/processorParam:PremultiplyAlpha=True +/processorParam:ResizeToPowerOfTwo=False +/processorParam:MakeSquare=False +/processorParam:TextureFormat=Color +/build:Models/ModelosVarios/MolinoProp/T_BMX_O.png + +#begin Models/ModelosVarios/MolinoProp/T_Chainfence_D.png +/importer:TextureImporter +/processor:TextureProcessor +/processorParam:ColorKeyColor=255,0,255,255 +/processorParam:ColorKeyEnabled=True +/processorParam:GenerateMipmaps=False +/processorParam:PremultiplyAlpha=True +/processorParam:ResizeToPowerOfTwo=False +/processorParam:MakeSquare=False +/processorParam:TextureFormat=Color +/build:Models/ModelosVarios/MolinoProp/T_Chainfence_D.png + +#begin Models/ModelosVarios/MolinoProp/T_Chainfence_O.png +/importer:TextureImporter +/processor:TextureProcessor +/processorParam:ColorKeyColor=255,0,255,255 +/processorParam:ColorKeyEnabled=True +/processorParam:GenerateMipmaps=False +/processorParam:PremultiplyAlpha=True +/processorParam:ResizeToPowerOfTwo=False +/processorParam:MakeSquare=False +/processorParam:TextureFormat=Color +/build:Models/ModelosVarios/MolinoProp/T_Chainfence_O.png + +#begin Models/ModelosVarios/MolinoProp/T_Lamppost_D.png +/importer:TextureImporter +/processor:TextureProcessor +/processorParam:ColorKeyColor=255,0,255,255 +/processorParam:ColorKeyEnabled=True +/processorParam:GenerateMipmaps=False +/processorParam:PremultiplyAlpha=True +/processorParam:ResizeToPowerOfTwo=False +/processorParam:MakeSquare=False +/processorParam:TextureFormat=Color +/build:Models/ModelosVarios/MolinoProp/T_Lamppost_D.png + +#begin Models/ModelosVarios/MolinoProp/T_Lamppost_O.png +/importer:TextureImporter +/processor:TextureProcessor +/processorParam:ColorKeyColor=255,0,255,255 +/processorParam:ColorKeyEnabled=True +/processorParam:GenerateMipmaps=False +/processorParam:PremultiplyAlpha=True +/processorParam:ResizeToPowerOfTwo=False +/processorParam:MakeSquare=False +/processorParam:TextureFormat=Color +/build:Models/ModelosVarios/MolinoProp/T_Lamppost_O.png + +#begin Models/ModelosVarios/MolinoProp/T_Windpump_D.png +/importer:TextureImporter +/processor:TextureProcessor +/processorParam:ColorKeyColor=255,0,255,255 +/processorParam:ColorKeyEnabled=True +/processorParam:GenerateMipmaps=False +/processorParam:PremultiplyAlpha=True +/processorParam:ResizeToPowerOfTwo=False +/processorParam:MakeSquare=False +/processorParam:TextureFormat=Color +/build:Models/ModelosVarios/MolinoProp/T_Windpump_D.png + +#begin Models/nature/rock/Rock_1_Glossiness.jpg +/importer:TextureImporter +/processor:TextureProcessor +/processorParam:ColorKeyColor=255,0,255,255 +/processorParam:ColorKeyEnabled=True +/processorParam:GenerateMipmaps=False +/processorParam:PremultiplyAlpha=True +/processorParam:ResizeToPowerOfTwo=False +/processorParam:MakeSquare=False +/processorParam:TextureFormat=Color +/build:Models/nature/rock/Rock_1_Glossiness.jpg + +#begin Models/nature/rock/Rock_1_Normal.jpg +/importer:TextureImporter +/processor:TextureProcessor +/processorParam:ColorKeyColor=255,0,255,255 +/processorParam:ColorKeyEnabled=True +/processorParam:GenerateMipmaps=False +/processorParam:PremultiplyAlpha=True +/processorParam:ResizeToPowerOfTwo=False +/processorParam:MakeSquare=False +/processorParam:TextureFormat=Color +/build:Models/nature/rock/Rock_1_Normal.jpg + +#begin Models/nature/rock/Rock_1_occlusion.jpg +/importer:TextureImporter +/processor:TextureProcessor +/processorParam:ColorKeyColor=255,0,255,255 +/processorParam:ColorKeyEnabled=True +/processorParam:GenerateMipmaps=False +/processorParam:PremultiplyAlpha=True +/processorParam:ResizeToPowerOfTwo=False +/processorParam:MakeSquare=False +/processorParam:TextureFormat=Color +/build:Models/nature/rock/Rock_1_occlusion.jpg + +#begin Models/nature/rock/Rock_1_Specular.jpg +/importer:TextureImporter +/processor:TextureProcessor +/processorParam:ColorKeyColor=255,0,255,255 +/processorParam:ColorKeyEnabled=True +/processorParam:GenerateMipmaps=False +/processorParam:PremultiplyAlpha=True +/processorParam:ResizeToPowerOfTwo=False +/processorParam:MakeSquare=False +/processorParam:TextureFormat=Color +/build:Models/nature/rock/Rock_1_Specular.jpg + +#begin Models/nature/rock/Rock_1.fbx +/importer:FbxImporter +/processor:ModelProcessor +/processorParam:ColorKeyColor=0,0,0,0 +/processorParam:ColorKeyEnabled=True +/processorParam:DefaultEffect=BasicEffect +/processorParam:GenerateMipmaps=True +/processorParam:GenerateTangentFrames=False +/processorParam:PremultiplyTextureAlpha=True +/processorParam:PremultiplyVertexColors=True +/processorParam:ResizeTexturesToPowerOfTwo=False +/processorParam:RotationX=0 +/processorParam:RotationY=0 +/processorParam:RotationZ=0 +/processorParam:Scale=1 +/processorParam:SwapWindingOrder=False +/processorParam:TextureFormat=Compressed +/build:Models/nature/rock/Rock_1.fbx + +#begin Models/nature/rock/Yeni klasör/Rock_1_Base_Color.jpg +/importer:TextureImporter +/processor:TextureProcessor +/processorParam:ColorKeyColor=255,0,255,255 +/processorParam:ColorKeyEnabled=True +/processorParam:GenerateMipmaps=True +/processorParam:PremultiplyAlpha=True +/processorParam:ResizeToPowerOfTwo=False +/processorParam:MakeSquare=False +/processorParam:TextureFormat=Color +/build:Models/nature/rock/Yeni klasör/Rock_1_Base_Color.jpg + +#begin Models/Panzer/Panzer.fbx +/importer:FbxImporter +/processor:ModelProcessor +/processorParam:ColorKeyColor=0,0,0,0 +/processorParam:ColorKeyEnabled=True +/processorParam:DefaultEffect=BasicEffect +/processorParam:GenerateMipmaps=True +/processorParam:GenerateTangentFrames=False +/processorParam:PremultiplyTextureAlpha=True +/processorParam:PremultiplyVertexColors=True +/processorParam:ResizeTexturesToPowerOfTwo=False +/processorParam:RotationX=0 +/processorParam:RotationY=0 +/processorParam:RotationZ=0 +/processorParam:Scale=1 +/processorParam:SwapWindingOrder=False +/processorParam:TextureFormat=Compressed +/build:Models/Panzer/Panzer.fbx + +#begin Models/Panzer/PzVI_Tiger_I_NM.dds +/importer:TextureImporter +/processor:TextureProcessor +/processorParam:ColorKeyColor=255,0,255,255 +/processorParam:ColorKeyEnabled=True +/processorParam:GenerateMipmaps=False +/processorParam:PremultiplyAlpha=True +/processorParam:ResizeToPowerOfTwo=False +/processorParam:MakeSquare=False +/processorParam:TextureFormat=Color +/build:Models/Panzer/PzVI_Tiger_I_NM.dds + +#begin Models/Panzer/PzVI_Tiger_I_SM.dds +/importer:TextureImporter +/processor:TextureProcessor +/processorParam:ColorKeyColor=255,0,255,255 +/processorParam:ColorKeyEnabled=True +/processorParam:GenerateMipmaps=False +/processorParam:PremultiplyAlpha=True +/processorParam:ResizeToPowerOfTwo=False +/processorParam:MakeSquare=False +/processorParam:TextureFormat=Color +/build:Models/Panzer/PzVI_Tiger_I_SM.dds + +#begin Models/Panzer/PzVI_Tiger_I_track_NM.dds +/importer:TextureImporter +/processor:TextureProcessor +/processorParam:ColorKeyColor=255,0,255,255 +/processorParam:ColorKeyEnabled=True +/processorParam:GenerateMipmaps=False +/processorParam:PremultiplyAlpha=True +/processorParam:ResizeToPowerOfTwo=False +/processorParam:MakeSquare=False +/processorParam:TextureFormat=Color +/build:Models/Panzer/PzVI_Tiger_I_track_NM.dds + +#begin Models/Panzer/PzVI_Tiger_I_track_SM.dds +/importer:TextureImporter +/processor:TextureProcessor +/processorParam:ColorKeyColor=255,0,255,255 +/processorParam:ColorKeyEnabled=True +/processorParam:GenerateMipmaps=False +/processorParam:PremultiplyAlpha=True +/processorParam:ResizeToPowerOfTwo=False +/processorParam:MakeSquare=False +/processorParam:TextureFormat=Color +/build:Models/Panzer/PzVI_Tiger_I_track_SM.dds + +#begin Models/Panzer/PzVI_Tiger_I_track.dds +/importer:TextureImporter +/processor:TextureProcessor +/processorParam:ColorKeyColor=255,0,255,255 +/processorParam:ColorKeyEnabled=True +/processorParam:GenerateMipmaps=False +/processorParam:PremultiplyAlpha=True +/processorParam:ResizeToPowerOfTwo=False +/processorParam:MakeSquare=False +/processorParam:TextureFormat=Color +/build:Models/Panzer/PzVI_Tiger_I_track.dds + +#begin Models/Panzer/PzVl_Tiger_I.dds +/importer:TextureImporter +/processor:TextureProcessor +/processorParam:ColorKeyColor=255,0,255,255 +/processorParam:ColorKeyEnabled=True +/processorParam:GenerateMipmaps=False +/processorParam:PremultiplyAlpha=True +/processorParam:ResizeToPowerOfTwo=False +/processorParam:MakeSquare=False +/processorParam:TextureFormat=Color +/build:Models/Panzer/PzVl_Tiger_I.dds + +#begin Models/skybox/cube.fbx +/importer:FbxImporter +/processor:ModelProcessor +/processorParam:ColorKeyColor=0,0,0,0 +/processorParam:ColorKeyEnabled=True +/processorParam:DefaultEffect=BasicEffect +/processorParam:GenerateMipmaps=True +/processorParam:GenerateTangentFrames=False +/processorParam:PremultiplyTextureAlpha=True +/processorParam:PremultiplyVertexColors=True +/processorParam:ResizeTexturesToPowerOfTwo=False +/processorParam:RotationX=0 +/processorParam:RotationY=0 +/processorParam:RotationZ=0 +/processorParam:Scale=1 +/processorParam:SwapWindingOrder=False +/processorParam:TextureFormat=Compressed +/build:Models/skybox/cube.fbx + +#begin Models/Snowy_Shack/Little_shack_DefaultMaterial_BaseColor.png +/importer:TextureImporter +/processor:TextureProcessor +/processorParam:ColorKeyColor=255,0,255,255 +/processorParam:ColorKeyEnabled=True +/processorParam:GenerateMipmaps=False +/processorParam:PremultiplyAlpha=True +/processorParam:ResizeToPowerOfTwo=False +/processorParam:MakeSquare=False +/processorParam:TextureFormat=Color +/build:Models/Snowy_Shack/Little_shack_DefaultMaterial_BaseColor.png + +#begin Models/Snowy_Shack/Little_shack_DefaultMaterial_Height.png +/importer:TextureImporter +/processor:TextureProcessor +/processorParam:ColorKeyColor=255,0,255,255 +/processorParam:ColorKeyEnabled=True +/processorParam:GenerateMipmaps=False +/processorParam:PremultiplyAlpha=True +/processorParam:ResizeToPowerOfTwo=False +/processorParam:MakeSquare=False +/processorParam:TextureFormat=Color +/build:Models/Snowy_Shack/Little_shack_DefaultMaterial_Height.png + +#begin Models/Snowy_Shack/Little_shack_DefaultMaterial_Metallic.png +/importer:TextureImporter +/processor:TextureProcessor +/processorParam:ColorKeyColor=255,0,255,255 +/processorParam:ColorKeyEnabled=True +/processorParam:GenerateMipmaps=False +/processorParam:PremultiplyAlpha=True +/processorParam:ResizeToPowerOfTwo=False +/processorParam:MakeSquare=False +/processorParam:TextureFormat=Color +/build:Models/Snowy_Shack/Little_shack_DefaultMaterial_Metallic.png + +#begin Models/Snowy_Shack/Little_shack_DefaultMaterial_Normal.png +/importer:TextureImporter +/processor:TextureProcessor +/processorParam:ColorKeyColor=255,0,255,255 +/processorParam:ColorKeyEnabled=True +/processorParam:GenerateMipmaps=False +/processorParam:PremultiplyAlpha=True +/processorParam:ResizeToPowerOfTwo=False +/processorParam:MakeSquare=False +/processorParam:TextureFormat=Color +/build:Models/Snowy_Shack/Little_shack_DefaultMaterial_Normal.png + +#begin Models/Snowy_Shack/Little_shack_DefaultMaterial_Roughness.png +/importer:TextureImporter +/processor:TextureProcessor +/processorParam:ColorKeyColor=255,0,255,255 +/processorParam:ColorKeyEnabled=True +/processorParam:GenerateMipmaps=False +/processorParam:PremultiplyAlpha=True +/processorParam:ResizeToPowerOfTwo=False +/processorParam:MakeSquare=False +/processorParam:TextureFormat=Color +/build:Models/Snowy_Shack/Little_shack_DefaultMaterial_Roughness.png + +#begin Models/Snowy_Shack/Little_shack.fbx +/importer:FbxImporter +/processor:ModelProcessor +/processorParam:ColorKeyColor=0,0,0,0 +/processorParam:ColorKeyEnabled=True +/processorParam:DefaultEffect=BasicEffect +/processorParam:GenerateMipmaps=True +/processorParam:GenerateTangentFrames=False +/processorParam:PremultiplyTextureAlpha=True +/processorParam:PremultiplyVertexColors=True +/processorParam:ResizeTexturesToPowerOfTwo=False +/processorParam:RotationX=0 +/processorParam:RotationY=0 +/processorParam:RotationZ=0 +/processorParam:Scale=1 +/processorParam:SwapWindingOrder=False +/processorParam:TextureFormat=Compressed +/build:Models/Snowy_Shack/Little_shack.fbx + +#begin Models/Snowy_Tank/Snowy_Tank.fbx +/importer:FbxImporter +/processor:ModelProcessor +/processorParam:ColorKeyColor=0,0,0,0 +/processorParam:ColorKeyEnabled=True +/processorParam:DefaultEffect=BasicEffect +/processorParam:GenerateMipmaps=True +/processorParam:GenerateTangentFrames=False +/processorParam:PremultiplyTextureAlpha=True +/processorParam:PremultiplyVertexColors=True +/processorParam:ResizeTexturesToPowerOfTwo=False +/processorParam:RotationX=0 +/processorParam:RotationY=0 +/processorParam:RotationZ=0 +/processorParam:Scale=1 +/processorParam:SwapWindingOrder=False +/processorParam:TextureFormat=Compressed +/build:Models/Snowy_Tank/Snowy_Tank.fbx + +#begin Models/Snowy_Tank/water tank_albedo.jpg +/importer:TextureImporter +/processor:TextureProcessor +/processorParam:ColorKeyColor=255,0,255,255 +/processorParam:ColorKeyEnabled=True +/processorParam:GenerateMipmaps=False +/processorParam:PremultiplyAlpha=True +/processorParam:ResizeToPowerOfTwo=False +/processorParam:MakeSquare=False +/processorParam:TextureFormat=Color +/build:Models/Snowy_Tank/water tank_albedo.jpg + +#begin Models/Snowy_Tank/water tank_AO.jpg +/importer:TextureImporter +/processor:TextureProcessor +/processorParam:ColorKeyColor=255,0,255,255 +/processorParam:ColorKeyEnabled=True +/processorParam:GenerateMipmaps=False +/processorParam:PremultiplyAlpha=True +/processorParam:ResizeToPowerOfTwo=False +/processorParam:MakeSquare=False +/processorParam:TextureFormat=Color +/build:Models/Snowy_Tank/water tank_AO.jpg + +#begin Models/Snowy_Tank/water tank_metallic.jpg +/importer:TextureImporter +/processor:TextureProcessor +/processorParam:ColorKeyColor=255,0,255,255 +/processorParam:ColorKeyEnabled=True +/processorParam:GenerateMipmaps=False +/processorParam:PremultiplyAlpha=True +/processorParam:ResizeToPowerOfTwo=False +/processorParam:MakeSquare=False +/processorParam:TextureFormat=Color +/build:Models/Snowy_Tank/water tank_metallic.jpg + +#begin Models/Snowy_Tank/water tank_normal.png +/importer:TextureImporter +/processor:TextureProcessor +/processorParam:ColorKeyColor=255,0,255,255 +/processorParam:ColorKeyEnabled=True +/processorParam:GenerateMipmaps=False +/processorParam:PremultiplyAlpha=True +/processorParam:ResizeToPowerOfTwo=False +/processorParam:MakeSquare=False +/processorParam:TextureFormat=Color +/build:Models/Snowy_Tank/water tank_normal.png + +#begin Models/Snowy_Tank/water tank_roughness.jpg +/importer:TextureImporter +/processor:TextureProcessor +/processorParam:ColorKeyColor=255,0,255,255 +/processorParam:ColorKeyEnabled=True +/processorParam:GenerateMipmaps=False +/processorParam:PremultiplyAlpha=True +/processorParam:ResizeToPowerOfTwo=False +/processorParam:MakeSquare=False +/processorParam:TextureFormat=Color +/build:Models/Snowy_Tank/water tank_roughness.jpg + +#begin Models/Stone_House/roof_ao.tga.png +/importer:TextureImporter +/processor:TextureProcessor +/processorParam:ColorKeyColor=255,0,255,255 +/processorParam:ColorKeyEnabled=True +/processorParam:GenerateMipmaps=False +/processorParam:PremultiplyAlpha=True +/processorParam:ResizeToPowerOfTwo=False +/processorParam:MakeSquare=False +/processorParam:TextureFormat=Color +/build:Models/Stone_House/roof_ao.tga.png + +#begin Models/Stone_House/Roof_col_roug.tga.png +/importer:TextureImporter +/processor:TextureProcessor +/processorParam:ColorKeyColor=255,0,255,255 +/processorParam:ColorKeyEnabled=True +/processorParam:GenerateMipmaps=False +/processorParam:PremultiplyAlpha=True +/processorParam:ResizeToPowerOfTwo=False +/processorParam:MakeSquare=False +/processorParam:TextureFormat=Color +/build:Models/Stone_House/Roof_col_roug.tga.png + +#begin Models/Stone_House/Roof_col.tga.png +/importer:TextureImporter +/processor:TextureProcessor +/processorParam:ColorKeyColor=255,0,255,255 +/processorParam:ColorKeyEnabled=True +/processorParam:GenerateMipmaps=False +/processorParam:PremultiplyAlpha=True +/processorParam:ResizeToPowerOfTwo=False +/processorParam:MakeSquare=False +/processorParam:TextureFormat=Color +/build:Models/Stone_House/Roof_col.tga.png + +#begin Models/Stone_House/Roof_met.tga.png +/importer:TextureImporter +/processor:TextureProcessor +/processorParam:ColorKeyColor=255,0,255,255 +/processorParam:ColorKeyEnabled=True +/processorParam:GenerateMipmaps=False +/processorParam:PremultiplyAlpha=True +/processorParam:ResizeToPowerOfTwo=False +/processorParam:MakeSquare=False +/processorParam:TextureFormat=Color +/build:Models/Stone_House/Roof_met.tga.png + +#begin Models/Stone_House/Roof_norm.tga.png +/importer:TextureImporter +/processor:TextureProcessor +/processorParam:ColorKeyColor=255,0,255,255 +/processorParam:ColorKeyEnabled=True +/processorParam:GenerateMipmaps=False +/processorParam:PremultiplyAlpha=True +/processorParam:ResizeToPowerOfTwo=False +/processorParam:MakeSquare=False +/processorParam:TextureFormat=Color +/build:Models/Stone_House/Roof_norm.tga.png + +#begin Models/Stone_House/StoneHouse.fbx +/importer:FbxImporter +/processor:ModelProcessor +/processorParam:ColorKeyColor=0,0,0,0 +/processorParam:ColorKeyEnabled=True +/processorParam:DefaultEffect=BasicEffect +/processorParam:GenerateMipmaps=True +/processorParam:GenerateTangentFrames=False +/processorParam:PremultiplyTextureAlpha=True +/processorParam:PremultiplyVertexColors=True +/processorParam:ResizeTexturesToPowerOfTwo=False +/processorParam:RotationX=0 +/processorParam:RotationY=0 +/processorParam:RotationZ=0 +/processorParam:Scale=1 +/processorParam:SwapWindingOrder=False +/processorParam:TextureFormat=Compressed +/build:Models/Stone_House/StoneHouse.fbx + +#begin Models/Stone_House/Wall_col.tga.png +/importer:TextureImporter +/processor:TextureProcessor +/processorParam:ColorKeyColor=255,0,255,255 +/processorParam:ColorKeyEnabled=True +/processorParam:GenerateMipmaps=False +/processorParam:PremultiplyAlpha=True +/processorParam:ResizeToPowerOfTwo=False +/processorParam:MakeSquare=False +/processorParam:TextureFormat=Color +/build:Models/Stone_House/Wall_col.tga.png + +#begin Models/Stone_House/wall_mat_ao.tga.png +/importer:TextureImporter +/processor:TextureProcessor +/processorParam:ColorKeyColor=255,0,255,255 +/processorParam:ColorKeyEnabled=True +/processorParam:GenerateMipmaps=False +/processorParam:PremultiplyAlpha=True +/processorParam:ResizeToPowerOfTwo=False +/processorParam:MakeSquare=False +/processorParam:TextureFormat=Color +/build:Models/Stone_House/wall_mat_ao.tga.png + +#begin Models/Stone_House/Wall_met.tga.png +/importer:TextureImporter +/processor:TextureProcessor +/processorParam:ColorKeyColor=255,0,255,255 +/processorParam:ColorKeyEnabled=True +/processorParam:GenerateMipmaps=False +/processorParam:PremultiplyAlpha=True +/processorParam:ResizeToPowerOfTwo=False +/processorParam:MakeSquare=False +/processorParam:TextureFormat=Color +/build:Models/Stone_House/Wall_met.tga.png + +#begin Models/Stone_House/Wall_norm.tga.png +/importer:TextureImporter +/processor:TextureProcessor +/processorParam:ColorKeyColor=255,0,255,255 +/processorParam:ColorKeyEnabled=True +/processorParam:GenerateMipmaps=False +/processorParam:PremultiplyAlpha=True +/processorParam:ResizeToPowerOfTwo=False +/processorParam:MakeSquare=False +/processorParam:TextureFormat=Color +/build:Models/Stone_House/Wall_norm.tga.png + +#begin Models/Stone_House/Wall_roug.tga.png +/importer:TextureImporter +/processor:TextureProcessor +/processorParam:ColorKeyColor=255,0,255,255 +/processorParam:ColorKeyEnabled=True +/processorParam:GenerateMipmaps=False +/processorParam:PremultiplyAlpha=True +/processorParam:ResizeToPowerOfTwo=False +/processorParam:MakeSquare=False +/processorParam:TextureFormat=Color +/build:Models/Stone_House/Wall_roug.tga.png + +#begin Models/Stone_House/Well_ao.tga.png +/importer:TextureImporter +/processor:TextureProcessor +/processorParam:ColorKeyColor=255,0,255,255 +/processorParam:ColorKeyEnabled=True +/processorParam:GenerateMipmaps=False +/processorParam:PremultiplyAlpha=True +/processorParam:ResizeToPowerOfTwo=False +/processorParam:MakeSquare=False +/processorParam:TextureFormat=Color +/build:Models/Stone_House/Well_ao.tga.png + +#begin Models/Stone_House/well_col.tga.png +/importer:TextureImporter +/processor:TextureProcessor +/processorParam:ColorKeyColor=255,0,255,255 +/processorParam:ColorKeyEnabled=True +/processorParam:GenerateMipmaps=False +/processorParam:PremultiplyAlpha=True +/processorParam:ResizeToPowerOfTwo=False +/processorParam:MakeSquare=False +/processorParam:TextureFormat=Color +/build:Models/Stone_House/well_col.tga.png + +#begin Models/Stone_House/well_met.tga.png +/importer:TextureImporter +/processor:TextureProcessor +/processorParam:ColorKeyColor=255,0,255,255 +/processorParam:ColorKeyEnabled=True +/processorParam:GenerateMipmaps=False +/processorParam:PremultiplyAlpha=True +/processorParam:ResizeToPowerOfTwo=False +/processorParam:MakeSquare=False +/processorParam:TextureFormat=Color +/build:Models/Stone_House/well_met.tga.png + +#begin Models/Stone_House/well_norm.tga.png +/importer:TextureImporter +/processor:TextureProcessor +/processorParam:ColorKeyColor=255,0,255,255 +/processorParam:ColorKeyEnabled=True +/processorParam:GenerateMipmaps=False +/processorParam:PremultiplyAlpha=True +/processorParam:ResizeToPowerOfTwo=False +/processorParam:MakeSquare=False +/processorParam:TextureFormat=Color +/build:Models/Stone_House/well_norm.tga.png + +#begin Models/Stone_House/well_roug.tga.png +/importer:TextureImporter +/processor:TextureProcessor +/processorParam:ColorKeyColor=255,0,255,255 +/processorParam:ColorKeyEnabled=True +/processorParam:GenerateMipmaps=False +/processorParam:PremultiplyAlpha=True +/processorParam:ResizeToPowerOfTwo=False +/processorParam:MakeSquare=False +/processorParam:TextureFormat=Color +/build:Models/Stone_House/well_roug.tga.png + +#begin Models/Stone_House/Wood_ao_all.tga.png +/importer:TextureImporter +/processor:TextureProcessor +/processorParam:ColorKeyColor=255,0,255,255 +/processorParam:ColorKeyEnabled=True +/processorParam:GenerateMipmaps=False +/processorParam:PremultiplyAlpha=True +/processorParam:ResizeToPowerOfTwo=False +/processorParam:MakeSquare=False +/processorParam:TextureFormat=Color +/build:Models/Stone_House/Wood_ao_all.tga.png + +#begin Models/Stone_House/Wood_col.tga.png +/importer:TextureImporter +/processor:TextureProcessor +/processorParam:ColorKeyColor=255,0,255,255 +/processorParam:ColorKeyEnabled=True +/processorParam:GenerateMipmaps=False +/processorParam:PremultiplyAlpha=True +/processorParam:ResizeToPowerOfTwo=False +/processorParam:MakeSquare=False +/processorParam:TextureFormat=Color +/build:Models/Stone_House/Wood_col.tga.png + +#begin Models/Stone_House/Wood_met.tga.png +/importer:TextureImporter +/processor:TextureProcessor +/processorParam:ColorKeyColor=255,0,255,255 +/processorParam:ColorKeyEnabled=True +/processorParam:GenerateMipmaps=False +/processorParam:PremultiplyAlpha=True +/processorParam:ResizeToPowerOfTwo=False +/processorParam:MakeSquare=False +/processorParam:TextureFormat=Color +/build:Models/Stone_House/Wood_met.tga.png + +#begin Models/Stone_House/Wood_norm.tga.png +/importer:TextureImporter +/processor:TextureProcessor +/processorParam:ColorKeyColor=255,0,255,255 +/processorParam:ColorKeyEnabled=True +/processorParam:GenerateMipmaps=False +/processorParam:PremultiplyAlpha=True +/processorParam:ResizeToPowerOfTwo=False +/processorParam:MakeSquare=False +/processorParam:TextureFormat=Color +/build:Models/Stone_House/Wood_norm.tga.png + +#begin Models/Stone_House/Wood_rough.tga.png +/importer:TextureImporter +/processor:TextureProcessor +/processorParam:ColorKeyColor=255,0,255,255 +/processorParam:ColorKeyEnabled=True +/processorParam:GenerateMipmaps=False +/processorParam:PremultiplyAlpha=True +/processorParam:ResizeToPowerOfTwo=False +/processorParam:MakeSquare=False +/processorParam:TextureFormat=Color +/build:Models/Stone_House/Wood_rough.tga.png + +#begin Models/TankBullets/Apcr.fbx +/importer:FbxImporter +/processor:ModelProcessor +/processorParam:ColorKeyColor=0,0,0,0 +/processorParam:ColorKeyEnabled=True +/processorParam:DefaultEffect=BasicEffect +/processorParam:GenerateMipmaps=True +/processorParam:GenerateTangentFrames=False +/processorParam:PremultiplyTextureAlpha=True +/processorParam:PremultiplyVertexColors=True +/processorParam:ResizeTexturesToPowerOfTwo=False +/processorParam:RotationX=0 +/processorParam:RotationY=0 +/processorParam:RotationZ=0 +/processorParam:Scale=1 +/processorParam:SwapWindingOrder=False +/processorParam:TextureFormat=Compressed +/build:Models/TankBullets/Apcr.fbx + +#begin Models/TankBullets/ApcrTexture.png +/importer:TextureImporter +/processor:TextureProcessor +/processorParam:ColorKeyColor=255,0,255,255 +/processorParam:ColorKeyEnabled=True +/processorParam:GenerateMipmaps=False +/processorParam:PremultiplyAlpha=True +/processorParam:ResizeToPowerOfTwo=False +/processorParam:MakeSquare=False +/processorParam:TextureFormat=Color +/build:Models/TankBullets/ApcrTexture.png + +#begin Music/movingTank.mp3 +/importer:Mp3Importer +/processor:SoundEffectProcessor +/processorParam:Quality=Best +/build:Music/movingTank.mp3 + +#begin Music/shootSound.mp3 +/importer:Mp3Importer +/processor:SoundEffectProcessor +/processorParam:Quality=Best +/build:Music/shootSound.mp3 + +#begin Music/TankGameBackgroundSound.mp3 +/importer:Mp3Importer +/processor:SongProcessor +/processorParam:Quality=Best +/build:Music/TankGameBackgroundSound.mp3 + +#begin Textures/casaAbandonada/Medieval_Brick_Texture_by_goodtextures.jpg +/importer:TextureImporter +/processor:TextureProcessor +/processorParam:ColorKeyColor=255,0,255,255 +/processorParam:ColorKeyEnabled=True +/processorParam:GenerateMipmaps=True +/processorParam:PremultiplyAlpha=True +/processorParam:ResizeToPowerOfTwo=False +/processorParam:MakeSquare=False +/processorParam:TextureFormat=Color +/build:Textures/casaAbandonada/Medieval_Brick_Texture_by_goodtextures.jpg + +#begin Textures/casaAbandonada/windows_0279_01_preview.jpg +/importer:TextureImporter +/processor:TextureProcessor +/processorParam:ColorKeyColor=255,0,255,255 +/processorParam:ColorKeyEnabled=True +/processorParam:GenerateMipmaps=True +/processorParam:PremultiplyAlpha=True +/processorParam:ResizeToPowerOfTwo=False +/processorParam:MakeSquare=False +/processorParam:TextureFormat=Color +/build:Textures/casaAbandonada/windows_0279_01_preview.jpg + +#begin Textures/casaAbandonada/WoodPlanksBare0051_3_M.jpg +/importer:TextureImporter +/processor:TextureProcessor +/processorParam:ColorKeyColor=255,0,255,255 +/processorParam:ColorKeyEnabled=True +/processorParam:GenerateMipmaps=True +/processorParam:PremultiplyAlpha=True +/processorParam:ResizeToPowerOfTwo=False +/processorParam:MakeSquare=False +/processorParam:TextureFormat=Color +/build:Textures/casaAbandonada/WoodPlanksBare0051_3_M.jpg + +#begin Textures/heighmap/Diffuse.jpg +/importer:TextureImporter +/processor:TextureProcessor +/processorParam:ColorKeyColor=255,0,255,255 +/processorParam:ColorKeyEnabled=True +/processorParam:GenerateMipmaps=False +/processorParam:PremultiplyAlpha=True +/processorParam:ResizeToPowerOfTwo=False +/processorParam:MakeSquare=False +/processorParam:TextureFormat=Color +/build:Textures/heighmap/Diffuse.jpg + +#begin Textures/heighmap/Displacement.jpg +/importer:TextureImporter +/processor:TextureProcessor +/processorParam:ColorKeyColor=255,0,255,255 +/processorParam:ColorKeyEnabled=True +/processorParam:GenerateMipmaps=False +/processorParam:PremultiplyAlpha=True +/processorParam:ResizeToPowerOfTwo=False +/processorParam:MakeSquare=False +/processorParam:TextureFormat=Color +/build:Textures/heighmap/Displacement.jpg + +#begin Textures/heighmap/heightmap.jpg +/importer:TextureImporter +/processor:TextureProcessor +/processorParam:ColorKeyColor=255,0,255,255 +/processorParam:ColorKeyEnabled=True +/processorParam:GenerateMipmaps=False +/processorParam:PremultiplyAlpha=True +/processorParam:ResizeToPowerOfTwo=False +/processorParam:MakeSquare=False +/processorParam:TextureFormat=Color +/build:Textures/heighmap/heightmap.jpg + +#begin Textures/heighmap/Normal Map.jpg +/importer:TextureImporter +/processor:TextureProcessor +/processorParam:ColorKeyColor=255,0,255,255 +/processorParam:ColorKeyEnabled=True +/processorParam:GenerateMipmaps=False +/processorParam:PremultiplyAlpha=True +/processorParam:ResizeToPowerOfTwo=False +/processorParam:MakeSquare=False +/processorParam:TextureFormat=Color +/build:Textures/heighmap/Normal Map.jpg + +#begin Textures/heighmap/roughness.jpg +/importer:TextureImporter +/processor:TextureProcessor +/processorParam:ColorKeyColor=255,0,255,255 +/processorParam:ColorKeyEnabled=True +/processorParam:GenerateMipmaps=False +/processorParam:PremultiplyAlpha=True +/processorParam:ResizeToPowerOfTwo=False +/processorParam:MakeSquare=False +/processorParam:TextureFormat=Color +/build:Textures/heighmap/roughness.jpg + +#begin Textures/heighmap/Snow.png +/importer:TextureImporter +/processor:TextureProcessor +/processorParam:ColorKeyColor=255,0,255,255 +/processorParam:ColorKeyEnabled=True +/processorParam:GenerateMipmaps=True +/processorParam:PremultiplyAlpha=True +/processorParam:ResizeToPowerOfTwo=False +/processorParam:MakeSquare=True +/processorParam:TextureFormat=Color +/build:Textures/heighmap/Snow.png + +#begin Textures/heighmap/Snow2.jpg +/importer:TextureImporter +/processor:TextureProcessor +/processorParam:ColorKeyColor=255,0,255,255 +/processorParam:ColorKeyEnabled=True +/processorParam:GenerateMipmaps=True +/processorParam:PremultiplyAlpha=True +/processorParam:ResizeToPowerOfTwo=False +/processorParam:MakeSquare=True +/processorParam:TextureFormat=Color +/build:Textures/heighmap/Snow2.jpg + +#begin Textures/HUD/lifebar_empty.png +/importer:TextureImporter +/processor:TextureProcessor +/processorParam:ColorKeyColor=255,0,255,255 +/processorParam:ColorKeyEnabled=True +/processorParam:GenerateMipmaps=False +/processorParam:PremultiplyAlpha=True +/processorParam:ResizeToPowerOfTwo=False +/processorParam:MakeSquare=False +/processorParam:TextureFormat=Color +/build:Textures/HUD/lifebar_empty.png + +#begin Textures/HUD/lifebar.png +/importer:TextureImporter +/processor:TextureProcessor +/processorParam:ColorKeyColor=255,0,255,255 +/processorParam:ColorKeyEnabled=True +/processorParam:GenerateMipmaps=False +/processorParam:PremultiplyAlpha=True +/processorParam:ResizeToPowerOfTwo=False +/processorParam:MakeSquare=False +/processorParam:TextureFormat=Color +/build:Textures/HUD/lifebar.png + +#begin Textures/HUD/lifebar/1.png +/importer:TextureImporter +/processor:TextureProcessor +/processorParam:ColorKeyColor=255,0,255,255 +/processorParam:ColorKeyEnabled=True +/processorParam:GenerateMipmaps=False +/processorParam:PremultiplyAlpha=True +/processorParam:ResizeToPowerOfTwo=False +/processorParam:MakeSquare=False +/processorParam:TextureFormat=Color +/build:Textures/HUD/lifebar/1.png + +#begin Textures/HUD/lifebar/10.png +/importer:TextureImporter +/processor:TextureProcessor +/processorParam:ColorKeyColor=255,0,255,255 +/processorParam:ColorKeyEnabled=True +/processorParam:GenerateMipmaps=False +/processorParam:PremultiplyAlpha=True +/processorParam:ResizeToPowerOfTwo=False +/processorParam:MakeSquare=False +/processorParam:TextureFormat=Color +/build:Textures/HUD/lifebar/10.png + +#begin Textures/HUD/lifebar/11.png +/importer:TextureImporter +/processor:TextureProcessor +/processorParam:ColorKeyColor=255,0,255,255 +/processorParam:ColorKeyEnabled=True +/processorParam:GenerateMipmaps=False +/processorParam:PremultiplyAlpha=True +/processorParam:ResizeToPowerOfTwo=False +/processorParam:MakeSquare=False +/processorParam:TextureFormat=Color +/build:Textures/HUD/lifebar/11.png + +#begin Textures/HUD/lifebar/2.png +/importer:TextureImporter +/processor:TextureProcessor +/processorParam:ColorKeyColor=255,0,255,255 +/processorParam:ColorKeyEnabled=True +/processorParam:GenerateMipmaps=False +/processorParam:PremultiplyAlpha=True +/processorParam:ResizeToPowerOfTwo=False +/processorParam:MakeSquare=False +/processorParam:TextureFormat=Color +/build:Textures/HUD/lifebar/2.png + +#begin Textures/HUD/lifebar/3.png +/importer:TextureImporter +/processor:TextureProcessor +/processorParam:ColorKeyColor=255,0,255,255 +/processorParam:ColorKeyEnabled=True +/processorParam:GenerateMipmaps=False +/processorParam:PremultiplyAlpha=True +/processorParam:ResizeToPowerOfTwo=False +/processorParam:MakeSquare=False +/processorParam:TextureFormat=Color +/build:Textures/HUD/lifebar/3.png + +#begin Textures/HUD/lifebar/4.png +/importer:TextureImporter +/processor:TextureProcessor +/processorParam:ColorKeyColor=255,0,255,255 +/processorParam:ColorKeyEnabled=True +/processorParam:GenerateMipmaps=False +/processorParam:PremultiplyAlpha=True +/processorParam:ResizeToPowerOfTwo=False +/processorParam:MakeSquare=False +/processorParam:TextureFormat=Color +/build:Textures/HUD/lifebar/4.png + +#begin Textures/HUD/lifebar/5.png +/importer:TextureImporter +/processor:TextureProcessor +/processorParam:ColorKeyColor=255,0,255,255 +/processorParam:ColorKeyEnabled=True +/processorParam:GenerateMipmaps=False +/processorParam:PremultiplyAlpha=True +/processorParam:ResizeToPowerOfTwo=False +/processorParam:MakeSquare=False +/processorParam:TextureFormat=Color +/build:Textures/HUD/lifebar/5.png + +#begin Textures/HUD/lifebar/6.png +/importer:TextureImporter +/processor:TextureProcessor +/processorParam:ColorKeyColor=255,0,255,255 +/processorParam:ColorKeyEnabled=True +/processorParam:GenerateMipmaps=False +/processorParam:PremultiplyAlpha=True +/processorParam:ResizeToPowerOfTwo=False +/processorParam:MakeSquare=False +/processorParam:TextureFormat=Color +/build:Textures/HUD/lifebar/6.png + +#begin Textures/HUD/lifebar/7.png +/importer:TextureImporter +/processor:TextureProcessor +/processorParam:ColorKeyColor=255,0,255,255 +/processorParam:ColorKeyEnabled=True +/processorParam:GenerateMipmaps=False +/processorParam:PremultiplyAlpha=True +/processorParam:ResizeToPowerOfTwo=False +/processorParam:MakeSquare=False +/processorParam:TextureFormat=Color +/build:Textures/HUD/lifebar/7.png + +#begin Textures/HUD/lifebar/8.png +/importer:TextureImporter +/processor:TextureProcessor +/processorParam:ColorKeyColor=255,0,255,255 +/processorParam:ColorKeyEnabled=True +/processorParam:GenerateMipmaps=False +/processorParam:PremultiplyAlpha=True +/processorParam:ResizeToPowerOfTwo=False +/processorParam:MakeSquare=False +/processorParam:TextureFormat=Color +/build:Textures/HUD/lifebar/8.png + +#begin Textures/HUD/lifebar/9.png +/importer:TextureImporter +/processor:TextureProcessor +/processorParam:ColorKeyColor=255,0,255,255 +/processorParam:ColorKeyEnabled=True +/processorParam:GenerateMipmaps=False +/processorParam:PremultiplyAlpha=True +/processorParam:ResizeToPowerOfTwo=False +/processorParam:MakeSquare=False +/processorParam:TextureFormat=Color +/build:Textures/HUD/lifebar/9.png + +#begin Textures/Menu/Default@4x.png +/importer:TextureImporter +/processor:TextureProcessor +/processorParam:ColorKeyColor=255,0,255,255 +/processorParam:ColorKeyEnabled=True +/processorParam:GenerateMipmaps=False +/processorParam:PremultiplyAlpha=True +/processorParam:ResizeToPowerOfTwo=False +/processorParam:MakeSquare=False +/processorParam:TextureFormat=Color +/build:Textures/Menu/Default@4x.png + +#begin Textures/Menu/PlayButton.png +/importer:TextureImporter +/processor:TextureProcessor +/processorParam:ColorKeyColor=255,0,255,255 +/processorParam:ColorKeyEnabled=True +/processorParam:GenerateMipmaps=False +/processorParam:PremultiplyAlpha=True +/processorParam:ResizeToPowerOfTwo=False +/processorParam:MakeSquare=False +/processorParam:TextureFormat=Color +/build:Textures/Menu/PlayButton.png + +#begin Textures/Menu/PlayButtonHover.png +/importer:TextureImporter +/processor:TextureProcessor +/processorParam:ColorKeyColor=255,0,255,255 +/processorParam:ColorKeyEnabled=True +/processorParam:GenerateMipmaps=False +/processorParam:PremultiplyAlpha=True +/processorParam:ResizeToPowerOfTwo=False +/processorParam:MakeSquare=False +/processorParam:TextureFormat=Color +/build:Textures/Menu/PlayButtonHover.png + +#begin Textures/Menu/RectangleButtonHover.png +/importer:TextureImporter +/processor:TextureProcessor +/processorParam:ColorKeyColor=255,0,255,255 +/processorParam:ColorKeyEnabled=True +/processorParam:GenerateMipmaps=False +/processorParam:PremultiplyAlpha=True +/processorParam:ResizeToPowerOfTwo=False +/processorParam:MakeSquare=False +/processorParam:TextureFormat=Color +/build:Textures/Menu/RectangleButtonHover.png + +#begin Textures/Menu/SoundOff.png +/importer:TextureImporter +/processor:TextureProcessor +/processorParam:ColorKeyColor=255,0,255,255 +/processorParam:ColorKeyEnabled=True +/processorParam:GenerateMipmaps=False +/processorParam:PremultiplyAlpha=True +/processorParam:ResizeToPowerOfTwo=False +/processorParam:MakeSquare=False +/processorParam:TextureFormat=Color +/build:Textures/Menu/SoundOff.png + +#begin Textures/Menu/SoundOffHover.png +/importer:TextureImporter +/processor:TextureProcessor +/processorParam:ColorKeyColor=255,0,255,255 +/processorParam:ColorKeyEnabled=True +/processorParam:GenerateMipmaps=False +/processorParam:PremultiplyAlpha=True +/processorParam:ResizeToPowerOfTwo=False +/processorParam:MakeSquare=False +/processorParam:TextureFormat=Color +/build:Textures/Menu/SoundOffHover.png + +#begin Textures/Menu/SoundOn.png +/importer:TextureImporter +/processor:TextureProcessor +/processorParam:ColorKeyColor=255,0,255,255 +/processorParam:ColorKeyEnabled=True +/processorParam:GenerateMipmaps=False +/processorParam:PremultiplyAlpha=True +/processorParam:ResizeToPowerOfTwo=False +/processorParam:MakeSquare=False +/processorParam:TextureFormat=Color +/build:Textures/Menu/SoundOn.png + +#begin Textures/Menu/SoundOnHover.png +/importer:TextureImporter +/processor:TextureProcessor +/processorParam:ColorKeyColor=255,0,255,255 +/processorParam:ColorKeyEnabled=True +/processorParam:GenerateMipmaps=False +/processorParam:PremultiplyAlpha=True +/processorParam:ResizeToPowerOfTwo=False +/processorParam:MakeSquare=False +/processorParam:TextureFormat=Color +/build:Textures/Menu/SoundOnHover.png + +#begin Textures/mouseTank.png +/importer:TextureImporter +/processor:TextureProcessor +/processorParam:ColorKeyColor=255,0,255,255 +/processorParam:ColorKeyEnabled=True +/processorParam:GenerateMipmaps=False +/processorParam:PremultiplyAlpha=True +/processorParam:ResizeToPowerOfTwo=False +/processorParam:MakeSquare=False +/processorParam:TextureFormat=Color +/build:Textures/mouseTank.png + +#begin Textures/proyectilMouse.png +/importer:TextureImporter +/processor:TextureProcessor +/processorParam:ColorKeyColor=255,0,255,255 +/processorParam:ColorKeyEnabled=True +/processorParam:GenerateMipmaps=False +/processorParam:PremultiplyAlpha=True +/processorParam:ResizeToPowerOfTwo=False +/processorParam:MakeSquare=False +/processorParam:TextureFormat=Color +/build:Textures/proyectilMouse.png + +#begin Textures/punto-de-mira.png +/importer:TextureImporter +/processor:TextureProcessor +/processorParam:ColorKeyColor=255,0,255,255 +/processorParam:ColorKeyEnabled=True +/processorParam:GenerateMipmaps=False +/processorParam:PremultiplyAlpha=True +/processorParam:ResizeToPowerOfTwo=False +/processorParam:MakeSquare=False +/processorParam:TextureFormat=Color +/build:Textures/punto-de-mira.png + +#begin Textures/skyboxes/empty-space/empty-space.dds +/importer:TextureImporter +/processor:TextureProcessor +/processorParam:ColorKeyColor=255,0,255,255 +/processorParam:ColorKeyEnabled=True +/processorParam:GenerateMipmaps=False +/processorParam:PremultiplyAlpha=True +/processorParam:ResizeToPowerOfTwo=False +/processorParam:MakeSquare=False +/processorParam:TextureFormat=Color +/build:Textures/skyboxes/empty-space/empty-space.dds + +#begin Textures/skyboxes/islands/islands.dds +/importer:TextureImporter +/processor:TextureProcessor +/processorParam:ColorKeyColor=255,0,255,255 +/processorParam:ColorKeyEnabled=True +/processorParam:GenerateMipmaps=False +/processorParam:PremultiplyAlpha=True +/processorParam:ResizeToPowerOfTwo=False +/processorParam:MakeSquare=False +/processorParam:TextureFormat=Color +/build:Textures/skyboxes/islands/islands.dds + +#begin Textures/skyboxes/mountain_skybox_hd.dds +/importer:TextureImporter +/processor:TextureProcessor +/processorParam:ColorKeyColor=255,0,255,255 +/processorParam:ColorKeyEnabled=True +/processorParam:GenerateMipmaps=False +/processorParam:PremultiplyAlpha=True +/processorParam:ResizeToPowerOfTwo=False +/processorParam:MakeSquare=False +/processorParam:TextureFormat=Color +/build:Textures/skyboxes/mountain_skybox_hd.dds + +#begin Textures/skyboxes/skybox/skybox.dds +/importer:TextureImporter +/processor:TextureProcessor +/processorParam:ColorKeyColor=255,0,255,255 +/processorParam:ColorKeyEnabled=True +/processorParam:GenerateMipmaps=False +/processorParam:PremultiplyAlpha=True +/processorParam:ResizeToPowerOfTwo=False +/processorParam:MakeSquare=False +/processorParam:TextureFormat=Color +/build:Textures/skyboxes/skybox/skybox.dds + +#begin Textures/skyboxes/sun-in-space/sun-in-space.dds +/importer:TextureImporter +/processor:TextureProcessor +/processorParam:ColorKeyColor=255,0,255,255 +/processorParam:ColorKeyEnabled=True +/processorParam:GenerateMipmaps=False +/processorParam:PremultiplyAlpha=True +/processorParam:ResizeToPowerOfTwo=False +/processorParam:MakeSquare=False +/processorParam:TextureFormat=Color +/build:Textures/skyboxes/sun-in-space/sun-in-space.dds + +#begin Textures/skyboxes/sunset/sunset.dds +/importer:TextureImporter +/processor:TextureProcessor +/processorParam:ColorKeyColor=255,0,255,255 +/processorParam:ColorKeyEnabled=True +/processorParam:GenerateMipmaps=False +/processorParam:PremultiplyAlpha=True +/processorParam:ResizeToPowerOfTwo=False +/processorParam:MakeSquare=False +/processorParam:TextureFormat=Color +/build:Textures/skyboxes/sunset/sunset.dds + +#begin Textures/Terrain/alpine_terrain_2k_color.png +/importer:TextureImporter +/processor:TextureProcessor +/processorParam:ColorKeyColor=255,0,255,255 +/processorParam:ColorKeyEnabled=True +/processorParam:GenerateMipmaps=False +/processorParam:PremultiplyAlpha=True +/processorParam:ResizeToPowerOfTwo=False +/processorParam:MakeSquare=False +/processorParam:TextureFormat=Color +/build:Textures/Terrain/alpine_terrain_2k_color.png + +#begin Textures/Terrain/playaround_3_normal_2k.png +/importer:TextureImporter +/processor:TextureProcessor +/processorParam:ColorKeyColor=255,0,255,255 +/processorParam:ColorKeyEnabled=True +/processorParam:GenerateMipmaps=False +/processorParam:PremultiplyAlpha=True +/processorParam:ResizeToPowerOfTwo=False +/processorParam:MakeSquare=False +/processorParam:TextureFormat=Color +/build:Textures/Terrain/playaround_3_normal_2k.png diff --git a/TGC.MonoGame.TP/Content/Effects/BasicShader.fx b/TGC.MonoGame.TP/Content/Effects/BasicShader.fx index fc8031f75..ce9d6df77 100644 --- a/TGC.MonoGame.TP/Content/Effects/BasicShader.fx +++ b/TGC.MonoGame.TP/Content/Effects/BasicShader.fx @@ -1,60 +1,237 @@ #if OPENGL - #define SV_POSITION POSITION - #define VS_SHADERMODEL vs_3_0 - #define PS_SHADERMODEL ps_3_0 +#define SV_POSITION POSITION +#define VS_SHADERMODEL vs_3_0 +#define PS_SHADERMODEL ps_3_0 #else - #define VS_SHADERMODEL vs_4_0_level_9_1 - #define PS_SHADERMODEL ps_4_0_level_9_1 +#define VS_SHADERMODEL vs_4_0_level_9_1 +#define PS_SHADERMODEL ps_4_0_level_9_1 #endif -// Custom Effects - https://docs.monogame.net/articles/content/custom_effects.html -// High-level shader language (HLSL) - https://docs.microsoft.com/en-us/windows/win32/direct3dhlsl/dx-graphics-hlsl -// Programming guide for HLSL - https://docs.microsoft.com/en-us/windows/win32/direct3dhlsl/dx-graphics-hlsl-pguide -// Reference for HLSL - https://docs.microsoft.com/en-us/windows/win32/direct3dhlsl/dx-graphics-hlsl-reference -// HLSL Semantics - https://docs.microsoft.com/en-us/windows/win32/direct3dhlsl/dx-graphics-hlsl-semantics +float4x4 World; // Matriz de mundo +float4x4 View; // Matriz de vista +float4x4 Projection; // Matriz de proyección -float4x4 World; -float4x4 View; -float4x4 Projection; +float3 ambientColor; // Color ambiental +float3 diffuseColor; // Color difuso +float3 specularColor; // Color especular +float KAmbient; // Factor de ambiente +float KDiffuse; // Factor difuso +float KSpecular; // Factor especular +float shininess; // Brillo especular -float3 DiffuseColor; +bool EnableTerrainDraw = false; +bool EnableGrass = false; +bool EnableTrees = false; +float onhit; -float Time = 0; +float3 lightPosition; +float3 eyePosition; + +float impacto; +float3 ImpactPosition; +float3 TankPosition; +float3 c_Esfera; + +float4 Plano_ST; + +float TrackOffset; +bool IsTrack; + +float alphaValue = 1; +float time = 0; + +texture texDiffuseMap; +sampler2D diffuseMap = sampler_state +{ + Texture = (texDiffuseMap); + ADDRESSU = WRAP; + ADDRESSV = WRAP; + MINFILTER = LINEAR; + MAGFILTER = LINEAR; + MIPFILTER = LINEAR; +}; + +texture texDiffuseMap2; +sampler2D diffuseMap2 = sampler_state +{ + Texture = (texDiffuseMap2); + ADDRESSU = MIRROR; + ADDRESSV = MIRROR; + MINFILTER = LINEAR; + MAGFILTER = LINEAR; + MIPFILTER = LINEAR; +}; + +texture texColorMap; +sampler2D colorMap = sampler_state +{ + Texture = (texColorMap); + ADDRESSU = WRAP; + ADDRESSV = WRAP; + MINFILTER = LINEAR; + MAGFILTER = LINEAR; + MIPFILTER = LINEAR; +}; + +texture ModelTexture; +sampler2D TextureSampler = sampler_state +{ + Texture = (ModelTexture); + MagFilter = Linear; + MinFilter = Linear; + AddressU = Wrap; + AddressV = Wrap; +}; struct VertexShaderInput { - float4 Position : POSITION0; + float4 Position : POSITION0; + float4 Normal : NORMAL; + float2 TextureCoordinate : TEXCOORD0; }; struct VertexShaderOutput { - float4 Position : SV_POSITION; + float4 Position : SV_POSITION; + float2 TextureCoordinate : TEXCOORD0; + float3 WorldPosition : TEXCOORD1; + float3 Normal : TEXCOORD2; +}; + +struct VS_INPUT +{ + float4 Position : POSITION0; + float2 Texcoord : TEXCOORD0; + float3 Normal : NORMAL0; +}; + +struct VS_OUTPUT +{ + float4 Position : POSITION0; + float2 Texcoord : TEXCOORD0; + float3 WorldPos : TEXCOORD1; + float3 WorldNormal : TEXCOORD2; }; -VertexShaderOutput MainVS(in VertexShaderInput input) +struct PS_INPUT { - // Clear the output - VertexShaderOutput output = (VertexShaderOutput)0; - // Model space to World space + float2 Texcoord : TEXCOORD0; + float3 WorldPos : TEXCOORD1; + float3 WorldNormal : TEXCOORD2; +}; + +VS_OUTPUT vs_RenderTerrain(VS_INPUT input) +{ + VS_OUTPUT output; + + //Proyectar posicion float4 worldPosition = mul(input.Position, World); - // World space to View space - float4 viewPosition = mul(worldPosition, View); - // View space to Projection space + float4 viewPosition = mul(worldPosition, View); output.Position = mul(viewPosition, Projection); + //Enviar Texcoord directamente + output.Texcoord = input.Texcoord; + + //todo: que le pase el inv trasp. word + float4x4 matInverseTransposeWorld = World; + output.WorldPos = worldPosition.xyz; + output.WorldNormal = mul(input.Normal, matInverseTransposeWorld).xyz; + + return output; +} + +float4 ps_RenderTerrain(VS_OUTPUT input) : COLOR0 +{ + if(EnableTerrainDraw == false) + return float4(0, 0, 0, 0); + + float3 N = normalize(input.WorldNormal); + float3 L = normalize(lightPosition - input.WorldPos); + float kd = saturate(0.4 + 0.7 * saturate(dot(N, L))); + + float3 c = tex2D(colorMap, input.Texcoord).rgb; + float3 tex1 = tex2D(diffuseMap, input.Texcoord * 31).rgb; + float3 tex2 = tex2D(diffuseMap2, input.Texcoord * 27).rgb; + float3 clr = lerp(lerp(tex1, tex2, c.r), c, -1.1); + + return float4(clr * kd, 1); +} + +VertexShaderOutput ImpactVS(in VertexShaderInput input) +{ + VertexShaderOutput output; + + // Transformaciones de espacio + float4 worldPosition = mul(input.Position, World); + + float4 viewPosition = mul(worldPosition, View); + output.Position = mul(viewPosition, Projection); + + // Pasar datos para el pixel shader + output.WorldPosition = worldPosition.xyz; + output.Normal = normalize(mul(input.Normal.xyz, (float3x3) World)); + + // Coordenadas de textura + output.TextureCoordinate = input.TextureCoordinate; + return output; } float4 MainPS(VertexShaderOutput input) : COLOR { - return float4(DiffuseColor, 1.0); + if (IsTrack) + { + input.TextureCoordinate.y += TrackOffset; + } + + float3 light = lightPosition; + + // Muestrear la textura + float4 texelColor = tex2D(TextureSampler, input.TextureCoordinate.xy); + // Si es un arbol invierte la direccion de la luz devido a que los arboles se dibujan alrevez + if (EnableTrees) + light = float3(lightPosition.x * -1, lightPosition.y, lightPosition.z * -1); + // Dirección de la luz (asumiendo luz solar, puedes ajustar según necesites) + float3 lightDirection = normalize(light - input.WorldPosition.xyz); + // Vector de vista + float3 viewDirection = normalize(eyePosition - input.WorldPosition.xyz); + // Vector semibrillante + float3 halfVector = normalize(lightDirection + viewDirection); + // Cálculo del componente difuso + float NdotL = saturate(dot(input.Normal, lightDirection)); + float3 diffuse = KDiffuse * diffuseColor * NdotL; + // Cálculo del componente especular + float NdotH = saturate(dot(input.Normal, halfVector)); + float3 specular = KSpecular * specularColor * pow(NdotH, shininess); + // Cálculo del componente ambiental + float3 ambient = KAmbient * ambientColor; + // Color final + float3 finalColor = ambient + diffuse + specular; + + float4 finalOutput; + + if(!EnableTerrainDraw) + finalOutput = texelColor * float4(finalColor, 1.0); + else + finalOutput = float4(finalColor, 1.0); + + finalOutput.rgb = saturate(finalOutput.rgb); + + return finalOutput; } -technique BasicColorDrawing +technique Impact + { - pass P0 - { - VertexShader = compile VS_SHADERMODEL MainVS(); - PixelShader = compile PS_SHADERMODEL MainPS(); - } -}; + pass P0 + { + VertexShader = compile VS_SHADERMODEL ImpactVS(); + PixelShader = compile PS_SHADERMODEL ps_RenderTerrain(); + } + + pass P1 + { + PixelShader = compile PS_SHADERMODEL MainPS(); + } + +}; \ No newline at end of file diff --git a/TGC.MonoGame.TP/Content/Effects/Gizmos.fx b/TGC.MonoGame.TP/Content/Effects/Gizmos.fx new file mode 100644 index 000000000..359001522 --- /dev/null +++ b/TGC.MonoGame.TP/Content/Effects/Gizmos.fx @@ -0,0 +1,61 @@ +#if OPENGL + #define SV_POSITION POSITION + #define VS_SHADERMODEL vs_3_0 + #define PS_SHADERMODEL ps_3_0 +#else + #define VS_SHADERMODEL vs_4_0_level_9_1 + #define PS_SHADERMODEL ps_4_0_level_9_1 +#endif + +float4x4 WorldViewProjection; +float3 Color; + +struct VertexShaderInput +{ + float4 Position : POSITION0; + float3 Color : COLOR0; +}; + +struct VertexShaderOutput +{ + float4 Position : SV_POSITION; + float3 Color : TEXCOORD0; +}; + +VertexShaderOutput MainVertexShader(in VertexShaderInput input) +{ + VertexShaderOutput output = (VertexShaderOutput)0; + + // Project position + output.Position = mul(input.Position, WorldViewProjection); + + // Propagate color + output.Color = input.Color; + + return output; +} + +float4 MainPixelShader(VertexShaderOutput input) : COLOR +{ + return float4(Color, 1.0); +} + +float4 BackgroundPixelShader(VertexShaderOutput input) : COLOR +{ + return float4(Color * 0.5, 1.0); +} + + +technique Gizmos +{ + pass Background + { + VertexShader = compile VS_SHADERMODEL MainVertexShader(); + PixelShader = compile PS_SHADERMODEL BackgroundPixelShader(); + } + pass Foreground + { + VertexShader = compile VS_SHADERMODEL MainVertexShader(); + PixelShader = compile PS_SHADERMODEL MainPixelShader(); + } +}; diff --git a/TGC.MonoGame.TP/Content/Effects/ShadowMap.fx b/TGC.MonoGame.TP/Content/Effects/ShadowMap.fx new file mode 100644 index 000000000..439f262b2 --- /dev/null +++ b/TGC.MonoGame.TP/Content/Effects/ShadowMap.fx @@ -0,0 +1,178 @@ +#if OPENGL +#define SV_POSITION POSITION +#define VS_SHADERMODEL vs_3_0 +#define PS_SHADERMODEL ps_3_0 +#else +#define VS_SHADERMODEL vs_4_0_level_9_1 +#define PS_SHADERMODEL ps_4_0_level_9_1 +#endif + +float4x4 WorldViewProjection; +float4x4 InverseTransposeWorld; +float4x4 World; +float4x4 LightViewProjection; + +float3 lightPosition; + +float2 shadowMapSize; + +static const float modulatedEpsilon = 0.000041200182749889791011810302734375; +static const float maxEpsilon = 0.000023200045689009130001068115234375; + +texture baseTexture; +sampler2D textureSampler = sampler_state +{ + Texture = (baseTexture); + MagFilter = Linear; + MinFilter = Linear; + AddressU = Clamp; + AddressV = Clamp; +}; + + +texture shadowMap; +sampler2D shadowMapSampler = +sampler_state +{ + Texture = ; + MinFilter = Point; + MagFilter = Point; + MipFilter = Point; + AddressU = Clamp; + AddressV = Clamp; +}; + +struct DepthPassVertexShaderInput +{ + float4 Position : POSITION0; +}; + +struct DepthPassVertexShaderOutput +{ + float4 Position : SV_POSITION; + float4 ScreenSpacePosition : TEXCOORD1; +}; + +struct ShadowedVertexShaderInput +{ + float4 Position : POSITION0; + float3 Normal : NORMAL; + float2 TextureCoordinates : TEXCOORD0; +}; + +struct ShadowedVertexShaderOutput +{ + float4 Position : SV_POSITION; + float2 TextureCoordinates : TEXCOORD0; + float4 WorldSpacePosition : TEXCOORD1; + float4 LightSpacePosition : TEXCOORD2; + float4 Normal : TEXCOORD3; +}; + + + + +DepthPassVertexShaderOutput DepthVS(in DepthPassVertexShaderInput input) +{ + DepthPassVertexShaderOutput output; + output.Position = mul(input.Position, WorldViewProjection); + output.ScreenSpacePosition = mul(input.Position, WorldViewProjection); + return output; +} + +float4 DepthPS(in DepthPassVertexShaderOutput input) : COLOR +{ + float depth = input.ScreenSpacePosition.z / input.ScreenSpacePosition.w; + return float4(depth, depth, depth, 1.0); +} + + + +ShadowedVertexShaderOutput MainVS(in ShadowedVertexShaderInput input) +{ + ShadowedVertexShaderOutput output; + output.Position = mul(input.Position, WorldViewProjection); + output.TextureCoordinates = input.TextureCoordinates; + output.WorldSpacePosition = mul(input.Position, World); + output.LightSpacePosition = mul(output.WorldSpacePosition, LightViewProjection); + output.Normal = mul(float4(input.Normal, 1), InverseTransposeWorld); + return output; +} + +float4 ShadowedPS(in ShadowedVertexShaderOutput input) : COLOR +{ + float3 lightSpacePosition = input.LightSpacePosition.xyz / input.LightSpacePosition.w; + float2 shadowMapTextureCoordinates = 0.5 * lightSpacePosition.xy + float2(0.5, 0.5); + shadowMapTextureCoordinates.y = 1.0f - shadowMapTextureCoordinates.y; + + + float3 normal = normalize(input.Normal.rgb); + float3 lightDirection = normalize(lightPosition - input.WorldSpacePosition.xyz); + float inclinationBias = max(modulatedEpsilon * (1.0 - dot(normal, lightDirection)), maxEpsilon); + + float shadowMapDepth = tex2D(shadowMapSampler, shadowMapTextureCoordinates).r + inclinationBias; + + // Compare the shadowmap with the REAL depth of this fragment + // in light space + float notInShadow = step(lightSpacePosition.z, shadowMapDepth); + + float4 baseColor = tex2D(textureSampler, input.TextureCoordinates); + baseColor.rgb *= 0.5 + 0.5 * notInShadow; + return baseColor; +} + +float4 ShadowedPCFPS(in ShadowedVertexShaderOutput input) : COLOR +{ + float3 lightSpacePosition = input.LightSpacePosition.xyz / input.LightSpacePosition.w; + float2 shadowMapTextureCoordinates = 0.5 * lightSpacePosition.xy + float2(0.5, 0.5); + shadowMapTextureCoordinates.y = 1.0f - shadowMapTextureCoordinates.y; + + float3 normal = normalize(input.Normal.rgb); + float3 lightDirection = normalize(lightPosition - input.WorldSpacePosition.xyz); + float inclinationBias = max(modulatedEpsilon * (1.0 - dot(normal, lightDirection)), maxEpsilon); + + // Sample and smooth the shadowmap + // Also perform the comparison inside the loop and average the result + float notInShadow = 0.0; + float2 texelSize = 1.0 / shadowMapSize; + for (int x = -1; x <= 1; x++) + for (int y = -1; y <= 1; y++) + { + float pcfDepth = tex2D(shadowMapSampler, shadowMapTextureCoordinates + float2(x, y) * texelSize).r + inclinationBias; + notInShadow += step(lightSpacePosition.z, pcfDepth) / 9.0; + } + + float4 baseColor = tex2D(textureSampler, input.TextureCoordinates); + baseColor.rgb *= 0.5 + 0.5 * notInShadow; + return baseColor; +} + + + + +technique DepthPass +{ + pass Pass0 + { + VertexShader = compile VS_SHADERMODEL DepthVS(); + PixelShader = compile PS_SHADERMODEL DepthPS(); + } +}; + +technique DrawShadowed +{ + pass Pass0 + { + VertexShader = compile VS_SHADERMODEL MainVS(); + PixelShader = compile PS_SHADERMODEL ShadowedPS(); + } +}; + +technique DrawShadowedPCF +{ + pass Pass0 + { + VertexShader = compile VS_SHADERMODEL MainVS(); + PixelShader = compile PS_SHADERMODEL ShadowedPCFPS(); + } +}; \ No newline at end of file diff --git a/TGC.MonoGame.TP/Content/Effects/Shadows.fx b/TGC.MonoGame.TP/Content/Effects/Shadows.fx new file mode 100644 index 000000000..38baf3e7e --- /dev/null +++ b/TGC.MonoGame.TP/Content/Effects/Shadows.fx @@ -0,0 +1,175 @@ +#if OPENGL +#define SV_POSITION POSITION +#define VS_SHADERMODEL vs_3_0 +#define PS_SHADERMODEL ps_3_0 +#else +#define VS_SHADERMODEL vs_4_0_level_9_1 +#define PS_SHADERMODEL ps_4_0_level_9_1 +#endif + +float4x4 WorldViewProjection; +float4x4 InverseTransposeWorld; +float4x4 World; +float4x4 LightViewProjection; + +float3 lightPosition; + +float2 shadowMapSize; + +static const float modulatedEpsilon = 0.000041200182749889791011810302734375; +static const float maxEpsilon = 0.000023200045689009130001068115234375; + +texture baseTexture; +sampler2D textureSampler = sampler_state +{ + Texture = (baseTexture); + MagFilter = Linear; + MinFilter = Linear; + AddressU = Clamp; + AddressV = Clamp; +}; + + +texture shadowMap; +sampler2D shadowMapSampler = +sampler_state +{ + Texture = ; + MinFilter = Point; + MagFilter = Point; + MipFilter = Point; + AddressU = Clamp; + AddressV = Clamp; +}; + +struct DepthPassVertexShaderInput +{ + float4 Position : POSITION0; +}; + +struct DepthPassVertexShaderOutput +{ + float4 Position : SV_POSITION; + float4 ScreenSpacePosition : TEXCOORD1; +}; + +struct ShadowedVertexShaderInput +{ + float4 Position : POSITION0; + float3 Normal : NORMAL; + float2 TextureCoordinates : TEXCOORD0; +}; + +struct ShadowedVertexShaderOutput +{ + float4 Position : SV_POSITION; + float2 TextureCoordinates : TEXCOORD0; + float4 WorldSpacePosition : TEXCOORD1; + float4 LightSpacePosition : TEXCOORD2; + float4 Normal : TEXCOORD3; +}; + + +DepthPassVertexShaderOutput DepthVS(in DepthPassVertexShaderInput input) +{ + DepthPassVertexShaderOutput output; + output.Position = mul(input.Position, WorldViewProjection); + output.ScreenSpacePosition = mul(input.Position, WorldViewProjection); + return output; +} + +float4 DepthPS(in DepthPassVertexShaderOutput input) : COLOR +{ + float depth = input.ScreenSpacePosition.z / input.ScreenSpacePosition.w; + return float4(depth, depth, depth, 1.0); +} + + +ShadowedVertexShaderOutput MainVS(in ShadowedVertexShaderInput input) +{ + ShadowedVertexShaderOutput output; + output.Position = mul(input.Position, WorldViewProjection); + output.TextureCoordinates = input.TextureCoordinates; + output.WorldSpacePosition = mul(input.Position, World); + output.LightSpacePosition = mul(output.WorldSpacePosition, LightViewProjection); + output.Normal = mul(float4(input.Normal, 1), InverseTransposeWorld); + return output; +} + +float4 ShadowedPS(in ShadowedVertexShaderOutput input) : COLOR +{ + float3 lightSpacePosition = input.LightSpacePosition.xyz / input.LightSpacePosition.w; + float2 shadowMapTextureCoordinates = 0.5 * lightSpacePosition.xy + float2(0.5, 0.5); + shadowMapTextureCoordinates.y = 1.0f - shadowMapTextureCoordinates.y; + + + float3 normal = normalize(input.Normal.rgb); + float3 lightDirection = normalize(lightPosition - input.WorldSpacePosition.xyz); + float inclinationBias = max(modulatedEpsilon * (1.0 - dot(normal, lightDirection)), maxEpsilon); + + float shadowMapDepth = tex2D(shadowMapSampler, shadowMapTextureCoordinates).r + inclinationBias; + + // Compare the shadowmap with the REAL depth of this fragment + // in light space + float notInShadow = step(lightSpacePosition.z, shadowMapDepth); + + float4 baseColor = tex2D(textureSampler, input.TextureCoordinates); + baseColor.rgb *= 0.5 + 0.5 * notInShadow; + return baseColor; +} + +float4 ShadowedPCFPS(in ShadowedVertexShaderOutput input) : COLOR +{ + float3 lightSpacePosition = input.LightSpacePosition.xyz / input.LightSpacePosition.w; + float2 shadowMapTextureCoordinates = 0.5 * lightSpacePosition.xy + float2(0.5, 0.5); + shadowMapTextureCoordinates.y = 1.0f - shadowMapTextureCoordinates.y; + + float3 normal = normalize(input.Normal.rgb); + float3 lightDirection = normalize(lightPosition - input.WorldSpacePosition.xyz); + float inclinationBias = max(modulatedEpsilon * (1.0 - dot(normal, lightDirection)), maxEpsilon); + + // Sample and smooth the shadowmap + // Also perform the comparison inside the loop and average the result + float notInShadow = 0.0; + float2 texelSize = 1.0 / shadowMapSize; + for (int x = -1; x <= 1; x++) + for (int y = -1; y <= 1; y++) + { + float pcfDepth = tex2D(shadowMapSampler, shadowMapTextureCoordinates + float2(x, y) * texelSize).r + inclinationBias; + notInShadow += step(lightSpacePosition.z, pcfDepth) / 9.0; + } + + float4 baseColor = tex2D(textureSampler, input.TextureCoordinates); + baseColor.rgb *= 0.5 + 0.5 * notInShadow; + return baseColor; +} + + + + +technique DepthPass +{ + pass Pass0 + { + VertexShader = compile VS_SHADERMODEL DepthVS(); + PixelShader = compile PS_SHADERMODEL DepthPS(); + } +}; + +technique DrawShadowed +{ + pass Pass0 + { + VertexShader = compile VS_SHADERMODEL MainVS(); + PixelShader = compile PS_SHADERMODEL ShadowedPS(); + } +}; + +technique DrawShadowedPCF +{ + pass Pass0 + { + VertexShader = compile VS_SHADERMODEL MainVS(); + PixelShader = compile PS_SHADERMODEL ShadowedPCFPS(); + } +}; \ No newline at end of file diff --git a/TGC.MonoGame.TP/Content/Effects/SkyBox.fx b/TGC.MonoGame.TP/Content/Effects/SkyBox.fx new file mode 100644 index 000000000..8de80d375 --- /dev/null +++ b/TGC.MonoGame.TP/Content/Effects/SkyBox.fx @@ -0,0 +1,64 @@ +#if OPENGL +#define SV_POSITION POSITION +#define VS_SHADERMODEL vs_3_0 +#define PS_SHADERMODEL ps_3_0 +#else +#define VS_SHADERMODEL vs_4_0_level_9_1 +#define PS_SHADERMODEL ps_4_0_level_9_1 +#endif + +float4x4 World; +float4x4 View; +float4x4 Projection; + +float3 CameraPosition; + +texture SkyBoxTexture; +samplerCUBE SkyBoxSampler = sampler_state +{ + texture = ; + magfilter = LINEAR; + minfilter = LINEAR; + mipfilter = LINEAR; + AddressU = Mirror; + AddressV = Mirror; +}; + +struct VertexShaderInput +{ + float4 Position : POSITION0; +}; + +struct VertexShaderOutput +{ + float4 Position : POSITION0; + float3 TextureCoordinate : TEXCOORD0; +}; + +VertexShaderOutput VertexShaderFunction(VertexShaderInput input) +{ + VertexShaderOutput output; + + float4 worldPosition = mul(input.Position, World); + float4 viewPosition = mul(worldPosition, View); + output.Position = mul(viewPosition, Projection); + + float4 VertexPosition = mul(input.Position, World); + output.TextureCoordinate = VertexPosition.xyz - CameraPosition; + + return output; +} + +float4 PixelShaderFunction(VertexShaderOutput input) : COLOR0 +{ + return float4(texCUBE(SkyBoxSampler, normalize(input.TextureCoordinate)).rgb, 1); +} + +technique Skybox +{ + pass Pass1 + { + VertexShader = compile VS_SHADERMODEL VertexShaderFunction(); + PixelShader = compile PS_SHADERMODEL PixelShaderFunction(); + } +} diff --git a/TGC.MonoGame.TP/Content/Effects/TextureMerge.fx b/TGC.MonoGame.TP/Content/Effects/TextureMerge.fx new file mode 100644 index 000000000..8fb618db5 --- /dev/null +++ b/TGC.MonoGame.TP/Content/Effects/TextureMerge.fx @@ -0,0 +1,70 @@ +#if OPENGL +#define SV_POSITION POSITION +#define VS_SHADERMODEL vs_3_0 +#define PS_SHADERMODEL ps_3_0 +#else +#define VS_SHADERMODEL vs_4_0_level_9_1 +#define PS_SHADERMODEL ps_4_0_level_9_1 +#endif + +float time; + +texture baseTexture; +sampler2D textureSampler = sampler_state +{ + Texture = (baseTexture); + MagFilter = Linear; + MinFilter = Linear; + AddressU = Clamp; + AddressV = Clamp; +}; + +texture overlayTexture; +sampler2D overlayTextureSampler = sampler_state +{ + Texture = (overlayTexture); + MagFilter = Linear; + MinFilter = Linear; + AddressU = Clamp; + AddressV = Clamp; +}; + + +struct VertexShaderInput +{ + float4 Position : POSITION0; + float2 TextureCoordinates : TEXCOORD0; +}; + +struct VertexShaderOutput +{ + float4 Position : SV_POSITION; + float2 TextureCoordinates : TEXCOORD0; +}; + + +VertexShaderOutput MainVS(in VertexShaderInput input) +{ + VertexShaderOutput output = (VertexShaderOutput) 0; + + output.Position = input.Position; + output.TextureCoordinates = input.TextureCoordinates; + + return output; +} + +float4 MergePS(VertexShaderOutput input) : COLOR +{ + float4 baseColor = tex2D(textureSampler, input.TextureCoordinates); + + return baseColor; +} + +technique Merge +{ + pass Pass0 + { + VertexShader = compile VS_SHADERMODEL MainVS(); + PixelShader = compile PS_SHADERMODEL MergePS(); + } +}; \ No newline at end of file diff --git a/TGC.MonoGame.TP/Content/Fonts/FiraCode/FiraCode-Bold.ttf b/TGC.MonoGame.TP/Content/Fonts/FiraCode/FiraCode-Bold.ttf new file mode 100644 index 000000000..9a3d65fb9 Binary files /dev/null and b/TGC.MonoGame.TP/Content/Fonts/FiraCode/FiraCode-Bold.ttf differ diff --git a/TGC.MonoGame.TP/Content/Fonts/FiraCode/FiraCode-Light.ttf b/TGC.MonoGame.TP/Content/Fonts/FiraCode/FiraCode-Light.ttf new file mode 100644 index 000000000..87ff0124b Binary files /dev/null and b/TGC.MonoGame.TP/Content/Fonts/FiraCode/FiraCode-Light.ttf differ diff --git a/TGC.MonoGame.TP/Content/Fonts/FiraCode/FiraCode-Medium.ttf b/TGC.MonoGame.TP/Content/Fonts/FiraCode/FiraCode-Medium.ttf new file mode 100644 index 000000000..7a9c38e04 Binary files /dev/null and b/TGC.MonoGame.TP/Content/Fonts/FiraCode/FiraCode-Medium.ttf differ diff --git a/TGC.MonoGame.TP/Content/Fonts/FiraCode/FiraCode-Regular.ttf b/TGC.MonoGame.TP/Content/Fonts/FiraCode/FiraCode-Regular.ttf new file mode 100644 index 000000000..b8a44d2db Binary files /dev/null and b/TGC.MonoGame.TP/Content/Fonts/FiraCode/FiraCode-Regular.ttf differ diff --git a/TGC.MonoGame.TP/Content/Fonts/FiraCode/FiraCode-SemiBold.ttf b/TGC.MonoGame.TP/Content/Fonts/FiraCode/FiraCode-SemiBold.ttf new file mode 100644 index 000000000..45cfed716 Binary files /dev/null and b/TGC.MonoGame.TP/Content/Fonts/FiraCode/FiraCode-SemiBold.ttf differ diff --git a/TGC.MonoGame.TP/Content/Fonts/FiraCode/OFL.txt b/TGC.MonoGame.TP/Content/Fonts/FiraCode/OFL.txt new file mode 100644 index 000000000..b1540b040 --- /dev/null +++ b/TGC.MonoGame.TP/Content/Fonts/FiraCode/OFL.txt @@ -0,0 +1,93 @@ +Copyright 2014-2020 The Fira Code Project Authors (https://github.com/tonsky/FiraCode) + +This Font Software is licensed under the SIL Open Font License, Version 1.1. +This license is copied below, and is also available with a FAQ at: +https://openfontlicense.org + + +----------------------------------------------------------- +SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007 +----------------------------------------------------------- + +PREAMBLE +The goals of the Open Font License (OFL) are to stimulate worldwide +development of collaborative font projects, to support the font creation +efforts of academic and linguistic communities, and to provide a free and +open framework in which fonts may be shared and improved in partnership +with others. + +The OFL allows the licensed fonts to be used, studied, modified and +redistributed freely as long as they are not sold by themselves. The +fonts, including any derivative works, can be bundled, embedded, +redistributed and/or sold with any software provided that any reserved +names are not used by derivative works. The fonts and derivatives, +however, cannot be released under any other type of license. The +requirement for fonts to remain under this license does not apply +to any document created using the fonts or their derivatives. + +DEFINITIONS +"Font Software" refers to the set of files released by the Copyright +Holder(s) under this license and clearly marked as such. This may +include source files, build scripts and documentation. + +"Reserved Font Name" refers to any names specified as such after the +copyright statement(s). + +"Original Version" refers to the collection of Font Software components as +distributed by the Copyright Holder(s). + +"Modified Version" refers to any derivative made by adding to, deleting, +or substituting -- in part or in whole -- any of the components of the +Original Version, by changing formats or by porting the Font Software to a +new environment. + +"Author" refers to any designer, engineer, programmer, technical +writer or other person who contributed to the Font Software. + +PERMISSION & CONDITIONS +Permission is hereby granted, free of charge, to any person obtaining +a copy of the Font Software, to use, study, copy, merge, embed, modify, +redistribute, and sell modified and unmodified copies of the Font +Software, subject to the following conditions: + +1) Neither the Font Software nor any of its individual components, +in Original or Modified Versions, may be sold by itself. + +2) Original or Modified Versions of the Font Software may be bundled, +redistributed and/or sold with any software, provided that each copy +contains the above copyright notice and this license. These can be +included either as stand-alone text files, human-readable headers or +in the appropriate machine-readable metadata fields within text or +binary files as long as those fields can be easily viewed by the user. + +3) No Modified Version of the Font Software may use the Reserved Font +Name(s) unless explicit written permission is granted by the corresponding +Copyright Holder. This restriction only applies to the primary font name as +presented to the users. + +4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font +Software shall not be used to promote, endorse or advertise any +Modified Version, except to acknowledge the contribution(s) of the +Copyright Holder(s) and the Author(s) or with their explicit written +permission. + +5) The Font Software, modified or unmodified, in part or in whole, +must be distributed entirely under this license, and must not be +distributed under any other license. The requirement for fonts to +remain under this license does not apply to any document created +using the Font Software. + +TERMINATION +This license becomes null and void if any of the above conditions are +not met. + +DISCLAIMER +THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT +OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE +COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM +OTHER DEALINGS IN THE FONT SOFTWARE. diff --git a/TGC.MonoGame.TP/Content/Fonts/FiraCode/README.txt b/TGC.MonoGame.TP/Content/Fonts/FiraCode/README.txt new file mode 100644 index 000000000..e70b485c3 --- /dev/null +++ b/TGC.MonoGame.TP/Content/Fonts/FiraCode/README.txt @@ -0,0 +1,67 @@ +Fira Code Variable Font +======================= + +This download contains Fira Code as both a variable font and static fonts. + +Fira Code is a variable font with this axis: + wght + +This means all the styles are contained in a single file: + FiraCode-VariableFont_wght.ttf + +If your app fully supports variable fonts, you can now pick intermediate styles +that aren’t available as static fonts. Not all apps support variable fonts, and +in those cases you can use the static font files for Fira Code: + static/FiraCode-Light.ttf + static/FiraCode-Regular.ttf + static/FiraCode-Medium.ttf + static/FiraCode-SemiBold.ttf + static/FiraCode-Bold.ttf + +Get started +----------- + +1. Install the font files you want to use + +2. Use your app's font picker to view the font family and all the +available styles + +Learn more about variable fonts +------------------------------- + + https://developers.google.com/web/fundamentals/design-and-ux/typography/variable-fonts + https://variablefonts.typenetwork.com + https://medium.com/variable-fonts + +In desktop apps + + https://theblog.adobe.com/can-variable-fonts-illustrator-cc + https://helpx.adobe.com/nz/photoshop/using/fonts.html#variable_fonts + +Online + + https://developers.google.com/fonts/docs/getting_started + https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Fonts/Variable_Fonts_Guide + https://developer.microsoft.com/en-us/microsoft-edge/testdrive/demos/variable-fonts + +Installing fonts + + MacOS: https://support.apple.com/en-us/HT201749 + Linux: https://www.google.com/search?q=how+to+install+a+font+on+gnu%2Blinux + Windows: https://support.microsoft.com/en-us/help/314960/how-to-install-or-remove-a-font-in-windows + +Android Apps + + https://developers.google.com/fonts/docs/android + https://developer.android.com/guide/topics/ui/look-and-feel/downloadable-fonts + +License +------- +Please read the full license text (OFL.txt) to understand the permissions, +restrictions and requirements for usage, redistribution, and modification. + +You can use them in your products & projects – print or digital, +commercial or otherwise. + +This isn't legal advice, please consider consulting a lawyer and see the full +license for all details. diff --git a/TGC.MonoGame.TP/Content/Fonts/Inconsolata/Inconsolata-Black.ttf b/TGC.MonoGame.TP/Content/Fonts/Inconsolata/Inconsolata-Black.ttf new file mode 100644 index 000000000..ab9c19b58 Binary files /dev/null and b/TGC.MonoGame.TP/Content/Fonts/Inconsolata/Inconsolata-Black.ttf differ diff --git a/TGC.MonoGame.TP/Content/Fonts/Inconsolata/Inconsolata-Bold.ttf b/TGC.MonoGame.TP/Content/Fonts/Inconsolata/Inconsolata-Bold.ttf new file mode 100644 index 000000000..c83ecca68 Binary files /dev/null and b/TGC.MonoGame.TP/Content/Fonts/Inconsolata/Inconsolata-Bold.ttf differ diff --git a/TGC.MonoGame.TP/Content/Fonts/Inconsolata/Inconsolata-ExtraBold.ttf b/TGC.MonoGame.TP/Content/Fonts/Inconsolata/Inconsolata-ExtraBold.ttf new file mode 100644 index 000000000..c1c1a2b58 Binary files /dev/null and b/TGC.MonoGame.TP/Content/Fonts/Inconsolata/Inconsolata-ExtraBold.ttf differ diff --git a/TGC.MonoGame.TP/Content/Fonts/Inconsolata/Inconsolata-ExtraLight.ttf b/TGC.MonoGame.TP/Content/Fonts/Inconsolata/Inconsolata-ExtraLight.ttf new file mode 100644 index 000000000..37320d6a4 Binary files /dev/null and b/TGC.MonoGame.TP/Content/Fonts/Inconsolata/Inconsolata-ExtraLight.ttf differ diff --git a/TGC.MonoGame.TP/Content/Fonts/Inconsolata/Inconsolata-Light.ttf b/TGC.MonoGame.TP/Content/Fonts/Inconsolata/Inconsolata-Light.ttf new file mode 100644 index 000000000..36b47d6d6 Binary files /dev/null and b/TGC.MonoGame.TP/Content/Fonts/Inconsolata/Inconsolata-Light.ttf differ diff --git a/TGC.MonoGame.TP/Content/Fonts/Inconsolata/Inconsolata-Medium.ttf b/TGC.MonoGame.TP/Content/Fonts/Inconsolata/Inconsolata-Medium.ttf new file mode 100644 index 000000000..86ba05ae8 Binary files /dev/null and b/TGC.MonoGame.TP/Content/Fonts/Inconsolata/Inconsolata-Medium.ttf differ diff --git a/TGC.MonoGame.TP/Content/Fonts/Inconsolata/Inconsolata-Regular.ttf b/TGC.MonoGame.TP/Content/Fonts/Inconsolata/Inconsolata-Regular.ttf new file mode 100644 index 000000000..d1241516b Binary files /dev/null and b/TGC.MonoGame.TP/Content/Fonts/Inconsolata/Inconsolata-Regular.ttf differ diff --git a/TGC.MonoGame.TP/Content/Fonts/Inconsolata/Inconsolata-SemiBold.ttf b/TGC.MonoGame.TP/Content/Fonts/Inconsolata/Inconsolata-SemiBold.ttf new file mode 100644 index 000000000..90e7dc54d Binary files /dev/null and b/TGC.MonoGame.TP/Content/Fonts/Inconsolata/Inconsolata-SemiBold.ttf differ diff --git a/TGC.MonoGame.TP/Content/Fonts/Inconsolata/Inconsolata_Condensed-Black.ttf b/TGC.MonoGame.TP/Content/Fonts/Inconsolata/Inconsolata_Condensed-Black.ttf new file mode 100644 index 000000000..64a8d75a6 Binary files /dev/null and b/TGC.MonoGame.TP/Content/Fonts/Inconsolata/Inconsolata_Condensed-Black.ttf differ diff --git a/TGC.MonoGame.TP/Content/Fonts/Inconsolata/Inconsolata_Condensed-Bold.ttf b/TGC.MonoGame.TP/Content/Fonts/Inconsolata/Inconsolata_Condensed-Bold.ttf new file mode 100644 index 000000000..fb970ee23 Binary files /dev/null and b/TGC.MonoGame.TP/Content/Fonts/Inconsolata/Inconsolata_Condensed-Bold.ttf differ diff --git a/TGC.MonoGame.TP/Content/Fonts/Inconsolata/Inconsolata_Condensed-ExtraBold.ttf b/TGC.MonoGame.TP/Content/Fonts/Inconsolata/Inconsolata_Condensed-ExtraBold.ttf new file mode 100644 index 000000000..ab555b1fe Binary files /dev/null and b/TGC.MonoGame.TP/Content/Fonts/Inconsolata/Inconsolata_Condensed-ExtraBold.ttf differ diff --git a/TGC.MonoGame.TP/Content/Fonts/Inconsolata/Inconsolata_Condensed-ExtraLight.ttf b/TGC.MonoGame.TP/Content/Fonts/Inconsolata/Inconsolata_Condensed-ExtraLight.ttf new file mode 100644 index 000000000..eded44d33 Binary files /dev/null and b/TGC.MonoGame.TP/Content/Fonts/Inconsolata/Inconsolata_Condensed-ExtraLight.ttf differ diff --git a/TGC.MonoGame.TP/Content/Fonts/Inconsolata/Inconsolata_Condensed-Light.ttf b/TGC.MonoGame.TP/Content/Fonts/Inconsolata/Inconsolata_Condensed-Light.ttf new file mode 100644 index 000000000..e456116b4 Binary files /dev/null and b/TGC.MonoGame.TP/Content/Fonts/Inconsolata/Inconsolata_Condensed-Light.ttf differ diff --git a/TGC.MonoGame.TP/Content/Fonts/Inconsolata/Inconsolata_Condensed-Medium.ttf b/TGC.MonoGame.TP/Content/Fonts/Inconsolata/Inconsolata_Condensed-Medium.ttf new file mode 100644 index 000000000..150c5fff2 Binary files /dev/null and b/TGC.MonoGame.TP/Content/Fonts/Inconsolata/Inconsolata_Condensed-Medium.ttf differ diff --git a/TGC.MonoGame.TP/Content/Fonts/Inconsolata/Inconsolata_Condensed-Regular.ttf b/TGC.MonoGame.TP/Content/Fonts/Inconsolata/Inconsolata_Condensed-Regular.ttf new file mode 100644 index 000000000..1384e4eb8 Binary files /dev/null and b/TGC.MonoGame.TP/Content/Fonts/Inconsolata/Inconsolata_Condensed-Regular.ttf differ diff --git a/TGC.MonoGame.TP/Content/Fonts/Inconsolata/Inconsolata_Condensed-SemiBold.ttf b/TGC.MonoGame.TP/Content/Fonts/Inconsolata/Inconsolata_Condensed-SemiBold.ttf new file mode 100644 index 000000000..72ae5347f Binary files /dev/null and b/TGC.MonoGame.TP/Content/Fonts/Inconsolata/Inconsolata_Condensed-SemiBold.ttf differ diff --git a/TGC.MonoGame.TP/Content/Fonts/Inconsolata/Inconsolata_Expanded-Black.ttf b/TGC.MonoGame.TP/Content/Fonts/Inconsolata/Inconsolata_Expanded-Black.ttf new file mode 100644 index 000000000..722cf800f Binary files /dev/null and b/TGC.MonoGame.TP/Content/Fonts/Inconsolata/Inconsolata_Expanded-Black.ttf differ diff --git a/TGC.MonoGame.TP/Content/Fonts/Inconsolata/Inconsolata_Expanded-Bold.ttf b/TGC.MonoGame.TP/Content/Fonts/Inconsolata/Inconsolata_Expanded-Bold.ttf new file mode 100644 index 000000000..6355433d7 Binary files /dev/null and b/TGC.MonoGame.TP/Content/Fonts/Inconsolata/Inconsolata_Expanded-Bold.ttf differ diff --git a/TGC.MonoGame.TP/Content/Fonts/Inconsolata/Inconsolata_Expanded-ExtraBold.ttf b/TGC.MonoGame.TP/Content/Fonts/Inconsolata/Inconsolata_Expanded-ExtraBold.ttf new file mode 100644 index 000000000..fade58098 Binary files /dev/null and b/TGC.MonoGame.TP/Content/Fonts/Inconsolata/Inconsolata_Expanded-ExtraBold.ttf differ diff --git a/TGC.MonoGame.TP/Content/Fonts/Inconsolata/Inconsolata_Expanded-ExtraLight.ttf b/TGC.MonoGame.TP/Content/Fonts/Inconsolata/Inconsolata_Expanded-ExtraLight.ttf new file mode 100644 index 000000000..3906a4d66 Binary files /dev/null and b/TGC.MonoGame.TP/Content/Fonts/Inconsolata/Inconsolata_Expanded-ExtraLight.ttf differ diff --git a/TGC.MonoGame.TP/Content/Fonts/Inconsolata/Inconsolata_Expanded-Light.ttf b/TGC.MonoGame.TP/Content/Fonts/Inconsolata/Inconsolata_Expanded-Light.ttf new file mode 100644 index 000000000..2695e27e6 Binary files /dev/null and b/TGC.MonoGame.TP/Content/Fonts/Inconsolata/Inconsolata_Expanded-Light.ttf differ diff --git a/TGC.MonoGame.TP/Content/Fonts/Inconsolata/Inconsolata_Expanded-Medium.ttf b/TGC.MonoGame.TP/Content/Fonts/Inconsolata/Inconsolata_Expanded-Medium.ttf new file mode 100644 index 000000000..0aa19497f Binary files /dev/null and b/TGC.MonoGame.TP/Content/Fonts/Inconsolata/Inconsolata_Expanded-Medium.ttf differ diff --git a/TGC.MonoGame.TP/Content/Fonts/Inconsolata/Inconsolata_Expanded-Regular.ttf b/TGC.MonoGame.TP/Content/Fonts/Inconsolata/Inconsolata_Expanded-Regular.ttf new file mode 100644 index 000000000..347312320 Binary files /dev/null and b/TGC.MonoGame.TP/Content/Fonts/Inconsolata/Inconsolata_Expanded-Regular.ttf differ diff --git a/TGC.MonoGame.TP/Content/Fonts/Inconsolata/Inconsolata_Expanded-SemiBold.ttf b/TGC.MonoGame.TP/Content/Fonts/Inconsolata/Inconsolata_Expanded-SemiBold.ttf new file mode 100644 index 000000000..1ad00cd74 Binary files /dev/null and b/TGC.MonoGame.TP/Content/Fonts/Inconsolata/Inconsolata_Expanded-SemiBold.ttf differ diff --git a/TGC.MonoGame.TP/Content/Fonts/Inconsolata/Inconsolata_ExtraCondensed-Black.ttf b/TGC.MonoGame.TP/Content/Fonts/Inconsolata/Inconsolata_ExtraCondensed-Black.ttf new file mode 100644 index 000000000..fac2e5d17 Binary files /dev/null and b/TGC.MonoGame.TP/Content/Fonts/Inconsolata/Inconsolata_ExtraCondensed-Black.ttf differ diff --git a/TGC.MonoGame.TP/Content/Fonts/Inconsolata/Inconsolata_ExtraCondensed-Bold.ttf b/TGC.MonoGame.TP/Content/Fonts/Inconsolata/Inconsolata_ExtraCondensed-Bold.ttf new file mode 100644 index 000000000..1ad2873e0 Binary files /dev/null and b/TGC.MonoGame.TP/Content/Fonts/Inconsolata/Inconsolata_ExtraCondensed-Bold.ttf differ diff --git a/TGC.MonoGame.TP/Content/Fonts/Inconsolata/Inconsolata_ExtraCondensed-ExtraBold.ttf b/TGC.MonoGame.TP/Content/Fonts/Inconsolata/Inconsolata_ExtraCondensed-ExtraBold.ttf new file mode 100644 index 000000000..4a2d1c4f2 Binary files /dev/null and b/TGC.MonoGame.TP/Content/Fonts/Inconsolata/Inconsolata_ExtraCondensed-ExtraBold.ttf differ diff --git a/TGC.MonoGame.TP/Content/Fonts/Inconsolata/Inconsolata_ExtraCondensed-ExtraLight.ttf b/TGC.MonoGame.TP/Content/Fonts/Inconsolata/Inconsolata_ExtraCondensed-ExtraLight.ttf new file mode 100644 index 000000000..0fa01420e Binary files /dev/null and b/TGC.MonoGame.TP/Content/Fonts/Inconsolata/Inconsolata_ExtraCondensed-ExtraLight.ttf differ diff --git a/TGC.MonoGame.TP/Content/Fonts/Inconsolata/Inconsolata_ExtraCondensed-Light.ttf b/TGC.MonoGame.TP/Content/Fonts/Inconsolata/Inconsolata_ExtraCondensed-Light.ttf new file mode 100644 index 000000000..df42dc5f7 Binary files /dev/null and b/TGC.MonoGame.TP/Content/Fonts/Inconsolata/Inconsolata_ExtraCondensed-Light.ttf differ diff --git a/TGC.MonoGame.TP/Content/Fonts/Inconsolata/Inconsolata_ExtraCondensed-Medium.ttf b/TGC.MonoGame.TP/Content/Fonts/Inconsolata/Inconsolata_ExtraCondensed-Medium.ttf new file mode 100644 index 000000000..e79c127e7 Binary files /dev/null and b/TGC.MonoGame.TP/Content/Fonts/Inconsolata/Inconsolata_ExtraCondensed-Medium.ttf differ diff --git a/TGC.MonoGame.TP/Content/Fonts/Inconsolata/Inconsolata_ExtraCondensed-Regular.ttf b/TGC.MonoGame.TP/Content/Fonts/Inconsolata/Inconsolata_ExtraCondensed-Regular.ttf new file mode 100644 index 000000000..27de6633f Binary files /dev/null and b/TGC.MonoGame.TP/Content/Fonts/Inconsolata/Inconsolata_ExtraCondensed-Regular.ttf differ diff --git a/TGC.MonoGame.TP/Content/Fonts/Inconsolata/Inconsolata_ExtraCondensed-SemiBold.ttf b/TGC.MonoGame.TP/Content/Fonts/Inconsolata/Inconsolata_ExtraCondensed-SemiBold.ttf new file mode 100644 index 000000000..4fd6d6ce5 Binary files /dev/null and b/TGC.MonoGame.TP/Content/Fonts/Inconsolata/Inconsolata_ExtraCondensed-SemiBold.ttf differ diff --git a/TGC.MonoGame.TP/Content/Fonts/Inconsolata/Inconsolata_ExtraExpanded-Black.ttf b/TGC.MonoGame.TP/Content/Fonts/Inconsolata/Inconsolata_ExtraExpanded-Black.ttf new file mode 100644 index 000000000..af80b1a43 Binary files /dev/null and b/TGC.MonoGame.TP/Content/Fonts/Inconsolata/Inconsolata_ExtraExpanded-Black.ttf differ diff --git a/TGC.MonoGame.TP/Content/Fonts/Inconsolata/Inconsolata_ExtraExpanded-Bold.ttf b/TGC.MonoGame.TP/Content/Fonts/Inconsolata/Inconsolata_ExtraExpanded-Bold.ttf new file mode 100644 index 000000000..36f58e8ce Binary files /dev/null and b/TGC.MonoGame.TP/Content/Fonts/Inconsolata/Inconsolata_ExtraExpanded-Bold.ttf differ diff --git a/TGC.MonoGame.TP/Content/Fonts/Inconsolata/Inconsolata_ExtraExpanded-ExtraBold.ttf b/TGC.MonoGame.TP/Content/Fonts/Inconsolata/Inconsolata_ExtraExpanded-ExtraBold.ttf new file mode 100644 index 000000000..7c726678c Binary files /dev/null and b/TGC.MonoGame.TP/Content/Fonts/Inconsolata/Inconsolata_ExtraExpanded-ExtraBold.ttf differ diff --git a/TGC.MonoGame.TP/Content/Fonts/Inconsolata/Inconsolata_ExtraExpanded-ExtraLight.ttf b/TGC.MonoGame.TP/Content/Fonts/Inconsolata/Inconsolata_ExtraExpanded-ExtraLight.ttf new file mode 100644 index 000000000..eb57f53bf Binary files /dev/null and b/TGC.MonoGame.TP/Content/Fonts/Inconsolata/Inconsolata_ExtraExpanded-ExtraLight.ttf differ diff --git a/TGC.MonoGame.TP/Content/Fonts/Inconsolata/Inconsolata_ExtraExpanded-Light.ttf b/TGC.MonoGame.TP/Content/Fonts/Inconsolata/Inconsolata_ExtraExpanded-Light.ttf new file mode 100644 index 000000000..fe45a9dd1 Binary files /dev/null and b/TGC.MonoGame.TP/Content/Fonts/Inconsolata/Inconsolata_ExtraExpanded-Light.ttf differ diff --git a/TGC.MonoGame.TP/Content/Fonts/Inconsolata/Inconsolata_ExtraExpanded-Medium.ttf b/TGC.MonoGame.TP/Content/Fonts/Inconsolata/Inconsolata_ExtraExpanded-Medium.ttf new file mode 100644 index 000000000..be733be42 Binary files /dev/null and b/TGC.MonoGame.TP/Content/Fonts/Inconsolata/Inconsolata_ExtraExpanded-Medium.ttf differ diff --git a/TGC.MonoGame.TP/Content/Fonts/Inconsolata/Inconsolata_ExtraExpanded-Regular.ttf b/TGC.MonoGame.TP/Content/Fonts/Inconsolata/Inconsolata_ExtraExpanded-Regular.ttf new file mode 100644 index 000000000..d5b6c77de Binary files /dev/null and b/TGC.MonoGame.TP/Content/Fonts/Inconsolata/Inconsolata_ExtraExpanded-Regular.ttf differ diff --git a/TGC.MonoGame.TP/Content/Fonts/Inconsolata/Inconsolata_ExtraExpanded-SemiBold.ttf b/TGC.MonoGame.TP/Content/Fonts/Inconsolata/Inconsolata_ExtraExpanded-SemiBold.ttf new file mode 100644 index 000000000..915f4efd4 Binary files /dev/null and b/TGC.MonoGame.TP/Content/Fonts/Inconsolata/Inconsolata_ExtraExpanded-SemiBold.ttf differ diff --git a/TGC.MonoGame.TP/Content/Fonts/Inconsolata/Inconsolata_SemiCondensed-Black.ttf b/TGC.MonoGame.TP/Content/Fonts/Inconsolata/Inconsolata_SemiCondensed-Black.ttf new file mode 100644 index 000000000..4132ca59c Binary files /dev/null and b/TGC.MonoGame.TP/Content/Fonts/Inconsolata/Inconsolata_SemiCondensed-Black.ttf differ diff --git a/TGC.MonoGame.TP/Content/Fonts/Inconsolata/Inconsolata_SemiCondensed-Bold.ttf b/TGC.MonoGame.TP/Content/Fonts/Inconsolata/Inconsolata_SemiCondensed-Bold.ttf new file mode 100644 index 000000000..a0d4881c3 Binary files /dev/null and b/TGC.MonoGame.TP/Content/Fonts/Inconsolata/Inconsolata_SemiCondensed-Bold.ttf differ diff --git a/TGC.MonoGame.TP/Content/Fonts/Inconsolata/Inconsolata_SemiCondensed-ExtraBold.ttf b/TGC.MonoGame.TP/Content/Fonts/Inconsolata/Inconsolata_SemiCondensed-ExtraBold.ttf new file mode 100644 index 000000000..1d844273d Binary files /dev/null and b/TGC.MonoGame.TP/Content/Fonts/Inconsolata/Inconsolata_SemiCondensed-ExtraBold.ttf differ diff --git a/TGC.MonoGame.TP/Content/Fonts/Inconsolata/Inconsolata_SemiCondensed-ExtraLight.ttf b/TGC.MonoGame.TP/Content/Fonts/Inconsolata/Inconsolata_SemiCondensed-ExtraLight.ttf new file mode 100644 index 000000000..a806219a7 Binary files /dev/null and b/TGC.MonoGame.TP/Content/Fonts/Inconsolata/Inconsolata_SemiCondensed-ExtraLight.ttf differ diff --git a/TGC.MonoGame.TP/Content/Fonts/Inconsolata/Inconsolata_SemiCondensed-Light.ttf b/TGC.MonoGame.TP/Content/Fonts/Inconsolata/Inconsolata_SemiCondensed-Light.ttf new file mode 100644 index 000000000..2c7b76529 Binary files /dev/null and b/TGC.MonoGame.TP/Content/Fonts/Inconsolata/Inconsolata_SemiCondensed-Light.ttf differ diff --git a/TGC.MonoGame.TP/Content/Fonts/Inconsolata/Inconsolata_SemiCondensed-Medium.ttf b/TGC.MonoGame.TP/Content/Fonts/Inconsolata/Inconsolata_SemiCondensed-Medium.ttf new file mode 100644 index 000000000..22c949fea Binary files /dev/null and b/TGC.MonoGame.TP/Content/Fonts/Inconsolata/Inconsolata_SemiCondensed-Medium.ttf differ diff --git a/TGC.MonoGame.TP/Content/Fonts/Inconsolata/Inconsolata_SemiCondensed-Regular.ttf b/TGC.MonoGame.TP/Content/Fonts/Inconsolata/Inconsolata_SemiCondensed-Regular.ttf new file mode 100644 index 000000000..5d454b84d Binary files /dev/null and b/TGC.MonoGame.TP/Content/Fonts/Inconsolata/Inconsolata_SemiCondensed-Regular.ttf differ diff --git a/TGC.MonoGame.TP/Content/Fonts/Inconsolata/Inconsolata_SemiCondensed-SemiBold.ttf b/TGC.MonoGame.TP/Content/Fonts/Inconsolata/Inconsolata_SemiCondensed-SemiBold.ttf new file mode 100644 index 000000000..2fb7a96ba Binary files /dev/null and b/TGC.MonoGame.TP/Content/Fonts/Inconsolata/Inconsolata_SemiCondensed-SemiBold.ttf differ diff --git a/TGC.MonoGame.TP/Content/Fonts/Inconsolata/Inconsolata_SemiExpanded-Black.ttf b/TGC.MonoGame.TP/Content/Fonts/Inconsolata/Inconsolata_SemiExpanded-Black.ttf new file mode 100644 index 000000000..a02e7f668 Binary files /dev/null and b/TGC.MonoGame.TP/Content/Fonts/Inconsolata/Inconsolata_SemiExpanded-Black.ttf differ diff --git a/TGC.MonoGame.TP/Content/Fonts/Inconsolata/Inconsolata_SemiExpanded-Bold.ttf b/TGC.MonoGame.TP/Content/Fonts/Inconsolata/Inconsolata_SemiExpanded-Bold.ttf new file mode 100644 index 000000000..d9f3186e1 Binary files /dev/null and b/TGC.MonoGame.TP/Content/Fonts/Inconsolata/Inconsolata_SemiExpanded-Bold.ttf differ diff --git a/TGC.MonoGame.TP/Content/Fonts/Inconsolata/Inconsolata_SemiExpanded-ExtraBold.ttf b/TGC.MonoGame.TP/Content/Fonts/Inconsolata/Inconsolata_SemiExpanded-ExtraBold.ttf new file mode 100644 index 000000000..dcdc2363a Binary files /dev/null and b/TGC.MonoGame.TP/Content/Fonts/Inconsolata/Inconsolata_SemiExpanded-ExtraBold.ttf differ diff --git a/TGC.MonoGame.TP/Content/Fonts/Inconsolata/Inconsolata_SemiExpanded-ExtraLight.ttf b/TGC.MonoGame.TP/Content/Fonts/Inconsolata/Inconsolata_SemiExpanded-ExtraLight.ttf new file mode 100644 index 000000000..41b1dd6a9 Binary files /dev/null and b/TGC.MonoGame.TP/Content/Fonts/Inconsolata/Inconsolata_SemiExpanded-ExtraLight.ttf differ diff --git a/TGC.MonoGame.TP/Content/Fonts/Inconsolata/Inconsolata_SemiExpanded-Light.ttf b/TGC.MonoGame.TP/Content/Fonts/Inconsolata/Inconsolata_SemiExpanded-Light.ttf new file mode 100644 index 000000000..c88d8bb9e Binary files /dev/null and b/TGC.MonoGame.TP/Content/Fonts/Inconsolata/Inconsolata_SemiExpanded-Light.ttf differ diff --git a/TGC.MonoGame.TP/Content/Fonts/Inconsolata/Inconsolata_SemiExpanded-Medium.ttf b/TGC.MonoGame.TP/Content/Fonts/Inconsolata/Inconsolata_SemiExpanded-Medium.ttf new file mode 100644 index 000000000..dd0d0e2a8 Binary files /dev/null and b/TGC.MonoGame.TP/Content/Fonts/Inconsolata/Inconsolata_SemiExpanded-Medium.ttf differ diff --git a/TGC.MonoGame.TP/Content/Fonts/Inconsolata/Inconsolata_SemiExpanded-Regular.ttf b/TGC.MonoGame.TP/Content/Fonts/Inconsolata/Inconsolata_SemiExpanded-Regular.ttf new file mode 100644 index 000000000..5b2ada50f Binary files /dev/null and b/TGC.MonoGame.TP/Content/Fonts/Inconsolata/Inconsolata_SemiExpanded-Regular.ttf differ diff --git a/TGC.MonoGame.TP/Content/Fonts/Inconsolata/Inconsolata_SemiExpanded-SemiBold.ttf b/TGC.MonoGame.TP/Content/Fonts/Inconsolata/Inconsolata_SemiExpanded-SemiBold.ttf new file mode 100644 index 000000000..6e6a60b00 Binary files /dev/null and b/TGC.MonoGame.TP/Content/Fonts/Inconsolata/Inconsolata_SemiExpanded-SemiBold.ttf differ diff --git a/TGC.MonoGame.TP/Content/Fonts/Inconsolata/Inconsolata_UltraCondensed-Black.ttf b/TGC.MonoGame.TP/Content/Fonts/Inconsolata/Inconsolata_UltraCondensed-Black.ttf new file mode 100644 index 000000000..a75999151 Binary files /dev/null and b/TGC.MonoGame.TP/Content/Fonts/Inconsolata/Inconsolata_UltraCondensed-Black.ttf differ diff --git a/TGC.MonoGame.TP/Content/Fonts/Inconsolata/Inconsolata_UltraCondensed-Bold.ttf b/TGC.MonoGame.TP/Content/Fonts/Inconsolata/Inconsolata_UltraCondensed-Bold.ttf new file mode 100644 index 000000000..3872e8504 Binary files /dev/null and b/TGC.MonoGame.TP/Content/Fonts/Inconsolata/Inconsolata_UltraCondensed-Bold.ttf differ diff --git a/TGC.MonoGame.TP/Content/Fonts/Inconsolata/Inconsolata_UltraCondensed-ExtraBold.ttf b/TGC.MonoGame.TP/Content/Fonts/Inconsolata/Inconsolata_UltraCondensed-ExtraBold.ttf new file mode 100644 index 000000000..98805f42e Binary files /dev/null and b/TGC.MonoGame.TP/Content/Fonts/Inconsolata/Inconsolata_UltraCondensed-ExtraBold.ttf differ diff --git a/TGC.MonoGame.TP/Content/Fonts/Inconsolata/Inconsolata_UltraCondensed-ExtraLight.ttf b/TGC.MonoGame.TP/Content/Fonts/Inconsolata/Inconsolata_UltraCondensed-ExtraLight.ttf new file mode 100644 index 000000000..dddd2c90e Binary files /dev/null and b/TGC.MonoGame.TP/Content/Fonts/Inconsolata/Inconsolata_UltraCondensed-ExtraLight.ttf differ diff --git a/TGC.MonoGame.TP/Content/Fonts/Inconsolata/Inconsolata_UltraCondensed-Light.ttf b/TGC.MonoGame.TP/Content/Fonts/Inconsolata/Inconsolata_UltraCondensed-Light.ttf new file mode 100644 index 000000000..93a1e6dd2 Binary files /dev/null and b/TGC.MonoGame.TP/Content/Fonts/Inconsolata/Inconsolata_UltraCondensed-Light.ttf differ diff --git a/TGC.MonoGame.TP/Content/Fonts/Inconsolata/Inconsolata_UltraCondensed-Medium.ttf b/TGC.MonoGame.TP/Content/Fonts/Inconsolata/Inconsolata_UltraCondensed-Medium.ttf new file mode 100644 index 000000000..1f00def3e Binary files /dev/null and b/TGC.MonoGame.TP/Content/Fonts/Inconsolata/Inconsolata_UltraCondensed-Medium.ttf differ diff --git a/TGC.MonoGame.TP/Content/Fonts/Inconsolata/Inconsolata_UltraCondensed-Regular.ttf b/TGC.MonoGame.TP/Content/Fonts/Inconsolata/Inconsolata_UltraCondensed-Regular.ttf new file mode 100644 index 000000000..a4d9bb338 Binary files /dev/null and b/TGC.MonoGame.TP/Content/Fonts/Inconsolata/Inconsolata_UltraCondensed-Regular.ttf differ diff --git a/TGC.MonoGame.TP/Content/Fonts/Inconsolata/Inconsolata_UltraCondensed-SemiBold.ttf b/TGC.MonoGame.TP/Content/Fonts/Inconsolata/Inconsolata_UltraCondensed-SemiBold.ttf new file mode 100644 index 000000000..1390ba82d Binary files /dev/null and b/TGC.MonoGame.TP/Content/Fonts/Inconsolata/Inconsolata_UltraCondensed-SemiBold.ttf differ diff --git a/TGC.MonoGame.TP/Content/Fonts/Inconsolata/Inconsolata_UltraExpanded-Black.ttf b/TGC.MonoGame.TP/Content/Fonts/Inconsolata/Inconsolata_UltraExpanded-Black.ttf new file mode 100644 index 000000000..4044cdc69 Binary files /dev/null and b/TGC.MonoGame.TP/Content/Fonts/Inconsolata/Inconsolata_UltraExpanded-Black.ttf differ diff --git a/TGC.MonoGame.TP/Content/Fonts/Inconsolata/Inconsolata_UltraExpanded-Bold.ttf b/TGC.MonoGame.TP/Content/Fonts/Inconsolata/Inconsolata_UltraExpanded-Bold.ttf new file mode 100644 index 000000000..df92f9dac Binary files /dev/null and b/TGC.MonoGame.TP/Content/Fonts/Inconsolata/Inconsolata_UltraExpanded-Bold.ttf differ diff --git a/TGC.MonoGame.TP/Content/Fonts/Inconsolata/Inconsolata_UltraExpanded-ExtraBold.ttf b/TGC.MonoGame.TP/Content/Fonts/Inconsolata/Inconsolata_UltraExpanded-ExtraBold.ttf new file mode 100644 index 000000000..22d0d6056 Binary files /dev/null and b/TGC.MonoGame.TP/Content/Fonts/Inconsolata/Inconsolata_UltraExpanded-ExtraBold.ttf differ diff --git a/TGC.MonoGame.TP/Content/Fonts/Inconsolata/Inconsolata_UltraExpanded-ExtraLight.ttf b/TGC.MonoGame.TP/Content/Fonts/Inconsolata/Inconsolata_UltraExpanded-ExtraLight.ttf new file mode 100644 index 000000000..388a167f0 Binary files /dev/null and b/TGC.MonoGame.TP/Content/Fonts/Inconsolata/Inconsolata_UltraExpanded-ExtraLight.ttf differ diff --git a/TGC.MonoGame.TP/Content/Fonts/Inconsolata/Inconsolata_UltraExpanded-Light.ttf b/TGC.MonoGame.TP/Content/Fonts/Inconsolata/Inconsolata_UltraExpanded-Light.ttf new file mode 100644 index 000000000..4a95cc1d3 Binary files /dev/null and b/TGC.MonoGame.TP/Content/Fonts/Inconsolata/Inconsolata_UltraExpanded-Light.ttf differ diff --git a/TGC.MonoGame.TP/Content/Fonts/Inconsolata/Inconsolata_UltraExpanded-Medium.ttf b/TGC.MonoGame.TP/Content/Fonts/Inconsolata/Inconsolata_UltraExpanded-Medium.ttf new file mode 100644 index 000000000..cba513712 Binary files /dev/null and b/TGC.MonoGame.TP/Content/Fonts/Inconsolata/Inconsolata_UltraExpanded-Medium.ttf differ diff --git a/TGC.MonoGame.TP/Content/Fonts/Inconsolata/Inconsolata_UltraExpanded-Regular.ttf b/TGC.MonoGame.TP/Content/Fonts/Inconsolata/Inconsolata_UltraExpanded-Regular.ttf new file mode 100644 index 000000000..a261b9e96 Binary files /dev/null and b/TGC.MonoGame.TP/Content/Fonts/Inconsolata/Inconsolata_UltraExpanded-Regular.ttf differ diff --git a/TGC.MonoGame.TP/Content/Fonts/Inconsolata/Inconsolata_UltraExpanded-SemiBold.ttf b/TGC.MonoGame.TP/Content/Fonts/Inconsolata/Inconsolata_UltraExpanded-SemiBold.ttf new file mode 100644 index 000000000..c122aa59c Binary files /dev/null and b/TGC.MonoGame.TP/Content/Fonts/Inconsolata/Inconsolata_UltraExpanded-SemiBold.ttf differ diff --git a/TGC.MonoGame.TP/Content/Fonts/arial.spritefont b/TGC.MonoGame.TP/Content/Fonts/arial.spritefont new file mode 100644 index 000000000..ec8ff87e8 --- /dev/null +++ b/TGC.MonoGame.TP/Content/Fonts/arial.spritefont @@ -0,0 +1,70 @@ + + + + + + + Arial + + + 12 + + + 0 + + + true + + + + + + + + + + + + ~ + + + + + + + + diff --git a/TGC.MonoGame.TP/Content/Fonts/camouflage/CamouflageD.ttf b/TGC.MonoGame.TP/Content/Fonts/camouflage/CamouflageD.ttf new file mode 100644 index 000000000..f3067d778 Binary files /dev/null and b/TGC.MonoGame.TP/Content/Fonts/camouflage/CamouflageD.ttf differ diff --git a/TGC.MonoGame.TP/Content/Fonts/camouflage/CamouflageJ.ttf b/TGC.MonoGame.TP/Content/Fonts/camouflage/CamouflageJ.ttf new file mode 100644 index 000000000..aa273b976 Binary files /dev/null and b/TGC.MonoGame.TP/Content/Fonts/camouflage/CamouflageJ.ttf differ diff --git a/TGC.MonoGame.TP/Content/Fonts/camouflage/CamouflageS.ttf b/TGC.MonoGame.TP/Content/Fonts/camouflage/CamouflageS.ttf new file mode 100644 index 000000000..c2958bbe2 Binary files /dev/null and b/TGC.MonoGame.TP/Content/Fonts/camouflage/CamouflageS.ttf differ diff --git a/TGC.MonoGame.TP/Content/Fonts/camouflage/CamouflageU.ttf b/TGC.MonoGame.TP/Content/Fonts/camouflage/CamouflageU.ttf new file mode 100644 index 000000000..a5a5e9c65 Binary files /dev/null and b/TGC.MonoGame.TP/Content/Fonts/camouflage/CamouflageU.ttf differ diff --git a/TGC.MonoGame.TP/Content/Fonts/camouflage/CamouflageW.ttf b/TGC.MonoGame.TP/Content/Fonts/camouflage/CamouflageW.ttf new file mode 100644 index 000000000..10c183e12 Binary files /dev/null and b/TGC.MonoGame.TP/Content/Fonts/camouflage/CamouflageW.ttf differ diff --git a/TGC.MonoGame.TP/Content/Fonts/octinvintage/octin vintage b rg.otf b/TGC.MonoGame.TP/Content/Fonts/octinvintage/octin vintage b rg.otf new file mode 100644 index 000000000..aec25a54e Binary files /dev/null and b/TGC.MonoGame.TP/Content/Fonts/octinvintage/octin vintage b rg.otf differ diff --git a/TGC.MonoGame.TP/Content/Fonts/warisover/WarIsOver.spritefont b/TGC.MonoGame.TP/Content/Fonts/warisover/WarIsOver.spritefont new file mode 100644 index 000000000..fa0953d5f --- /dev/null +++ b/TGC.MonoGame.TP/Content/Fonts/warisover/WarIsOver.spritefont @@ -0,0 +1,60 @@ + + + + + + + WarIsOver + + + 20 + + + 0 + + + true + + + + + + + + + + + + ~ + + + + diff --git a/TGC.MonoGame.TP/Content/Fonts/warisover/WarIsOver.ttf b/TGC.MonoGame.TP/Content/Fonts/warisover/WarIsOver.ttf new file mode 100644 index 000000000..ff9e54ad3 Binary files /dev/null and b/TGC.MonoGame.TP/Content/Fonts/warisover/WarIsOver.ttf differ diff --git a/TGC.MonoGame.TP/Content/Models/64Trees/firs_1.fbx b/TGC.MonoGame.TP/Content/Models/64Trees/firs_1.fbx new file mode 100644 index 000000000..35937fb8f --- /dev/null +++ b/TGC.MonoGame.TP/Content/Models/64Trees/firs_1.fbx @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:9e35256e9420a4bf2bb5517e861b1e1250596738f179cb12bffda07721019ed8 +size 45537580 diff --git a/TGC.MonoGame.TP/Content/Models/64Trees/nature_bark_fir_01_l_0001.jpg b/TGC.MonoGame.TP/Content/Models/64Trees/nature_bark_fir_01_l_0001.jpg new file mode 100644 index 000000000..b6e4bb80f --- /dev/null +++ b/TGC.MonoGame.TP/Content/Models/64Trees/nature_bark_fir_01_l_0001.jpg @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:8443be1d81f646032494a52c5c412137ac239e9d154f625332307712bc868505 +size 2589699 diff --git a/TGC.MonoGame.TP/Content/Models/64Trees/nature_bark_fir_01_l_0001_b.png b/TGC.MonoGame.TP/Content/Models/64Trees/nature_bark_fir_01_l_0001_b.png new file mode 100644 index 000000000..11115e2e3 --- /dev/null +++ b/TGC.MonoGame.TP/Content/Models/64Trees/nature_bark_fir_01_l_0001_b.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:8fa79c6283a7aff9e1769fd2ca4d0a9f2e0c3c841717f11f7602fb2387f20c5d +size 2388150 diff --git a/TGC.MonoGame.TP/Content/Models/GermanModel/Eye_AO.jpeg b/TGC.MonoGame.TP/Content/Models/GermanModel/Eye_AO.jpeg new file mode 100644 index 000000000..0a2e2b96b --- /dev/null +++ b/TGC.MonoGame.TP/Content/Models/GermanModel/Eye_AO.jpeg @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:b32e364b4fcdb981b0820d89afb63764269688dba77b58209b2e97e811edc3c2 +size 488021 diff --git a/TGC.MonoGame.TP/Content/Models/GermanModel/Eye_albedo.jpeg b/TGC.MonoGame.TP/Content/Models/GermanModel/Eye_albedo.jpeg new file mode 100644 index 000000000..8750e6f4e --- /dev/null +++ b/TGC.MonoGame.TP/Content/Models/GermanModel/Eye_albedo.jpeg @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:a5dacb95ddba3275f78d28262c6afb7d389973ab8c80fc754f3ac63a2e3ac40e +size 460083 diff --git a/TGC.MonoGame.TP/Content/Models/GermanModel/Eye_metallic.jpeg b/TGC.MonoGame.TP/Content/Models/GermanModel/Eye_metallic.jpeg new file mode 100644 index 000000000..d4381c6dc --- /dev/null +++ b/TGC.MonoGame.TP/Content/Models/GermanModel/Eye_metallic.jpeg @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:a23e17776a02a154eb554053dee6590c8bd691b9832f6d477e93c0db267023a3 +size 66163 diff --git a/TGC.MonoGame.TP/Content/Models/GermanModel/Eye_normal.jpeg b/TGC.MonoGame.TP/Content/Models/GermanModel/Eye_normal.jpeg new file mode 100644 index 000000000..06de9dcbc --- /dev/null +++ b/TGC.MonoGame.TP/Content/Models/GermanModel/Eye_normal.jpeg @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:b8deb05cabcbc55830a0ab9b4b3f7bd21cb82c61dea1aaed199b0dee3aea2b7e +size 96518 diff --git a/TGC.MonoGame.TP/Content/Models/GermanModel/Gear_AO.jpeg b/TGC.MonoGame.TP/Content/Models/GermanModel/Gear_AO.jpeg new file mode 100644 index 000000000..479d73780 --- /dev/null +++ b/TGC.MonoGame.TP/Content/Models/GermanModel/Gear_AO.jpeg @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:ad46c974044b6c56ebff6e5b2a48f7093a1a3fd2a59f66c7853bc5d663bc614b +size 401619 diff --git a/TGC.MonoGame.TP/Content/Models/GermanModel/Gear_albedo.jpeg b/TGC.MonoGame.TP/Content/Models/GermanModel/Gear_albedo.jpeg new file mode 100644 index 000000000..f13c13723 --- /dev/null +++ b/TGC.MonoGame.TP/Content/Models/GermanModel/Gear_albedo.jpeg @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:131c69b6721f74d799d505309e2f46d8d349927a5b2a58a58053913ea46f4232 +size 256861 diff --git a/TGC.MonoGame.TP/Content/Models/GermanModel/Gear_metallic.jpeg b/TGC.MonoGame.TP/Content/Models/GermanModel/Gear_metallic.jpeg new file mode 100644 index 000000000..9dfc75901 --- /dev/null +++ b/TGC.MonoGame.TP/Content/Models/GermanModel/Gear_metallic.jpeg @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:8e2e18a08ba38ade9e083cf970be3b5d807cae31ed715e3c390adde599d9ec3e +size 109220 diff --git a/TGC.MonoGame.TP/Content/Models/GermanModel/Gear_normal.jpeg b/TGC.MonoGame.TP/Content/Models/GermanModel/Gear_normal.jpeg new file mode 100644 index 000000000..af113e6ad --- /dev/null +++ b/TGC.MonoGame.TP/Content/Models/GermanModel/Gear_normal.jpeg @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:7e266afa02b2985e265475a7a34326403cb713b903c345a919f8045563cb7502 +size 499044 diff --git a/TGC.MonoGame.TP/Content/Models/GermanModel/Gear_roughness.jpeg b/TGC.MonoGame.TP/Content/Models/GermanModel/Gear_roughness.jpeg new file mode 100644 index 000000000..0d9179660 --- /dev/null +++ b/TGC.MonoGame.TP/Content/Models/GermanModel/Gear_roughness.jpeg @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:be5093bae245c8f47d2bb131eb58354c9eae4f456830c686c53e07aa07f24f22 +size 594977 diff --git a/TGC.MonoGame.TP/Content/Models/GermanModel/GermanSoldier.fbx b/TGC.MonoGame.TP/Content/Models/GermanModel/GermanSoldier.fbx new file mode 100644 index 000000000..e367d1586 --- /dev/null +++ b/TGC.MonoGame.TP/Content/Models/GermanModel/GermanSoldier.fbx @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:132fca458daa8ab182905ab2cc597c29b895f8a7291b7d5957b5f2b388f01372 +size 2302944 diff --git a/TGC.MonoGame.TP/Content/Models/GermanModel/GermanSoldier_1.fbx b/TGC.MonoGame.TP/Content/Models/GermanModel/GermanSoldier_1.fbx new file mode 100644 index 000000000..e7a6e9b0e --- /dev/null +++ b/TGC.MonoGame.TP/Content/Models/GermanModel/GermanSoldier_1.fbx @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:46fab1ac903f1a3617e74624e4cd490e9d3fe55fb38e83943b673896d35493ee +size 2641120 diff --git a/TGC.MonoGame.TP/Content/Models/GermanModel/GermanSoldier_2.fbx b/TGC.MonoGame.TP/Content/Models/GermanModel/GermanSoldier_2.fbx new file mode 100644 index 000000000..e788995ae --- /dev/null +++ b/TGC.MonoGame.TP/Content/Models/GermanModel/GermanSoldier_2.fbx @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:ff4d045f6b990ddb51bd647de8c5ae4747089dc55593b26c608439ec9a1d8723 +size 2908640 diff --git a/TGC.MonoGame.TP/Content/Models/GermanModel/Skin_AO.jpeg b/TGC.MonoGame.TP/Content/Models/GermanModel/Skin_AO.jpeg new file mode 100644 index 000000000..b28c8cb01 --- /dev/null +++ b/TGC.MonoGame.TP/Content/Models/GermanModel/Skin_AO.jpeg @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:6e8a08a449741c6f305445a68548075359175450f749b304d067758b8a487259 +size 637434 diff --git a/TGC.MonoGame.TP/Content/Models/GermanModel/Skin_albedo.jpeg b/TGC.MonoGame.TP/Content/Models/GermanModel/Skin_albedo.jpeg new file mode 100644 index 000000000..c388f58dc --- /dev/null +++ b/TGC.MonoGame.TP/Content/Models/GermanModel/Skin_albedo.jpeg @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:714a60a1e3bf8094042e7309a50fe76149dc30307a05b9e12c10a20341b46966 +size 377445 diff --git a/TGC.MonoGame.TP/Content/Models/GermanModel/Skin_metallic.jpeg b/TGC.MonoGame.TP/Content/Models/GermanModel/Skin_metallic.jpeg new file mode 100644 index 000000000..d4381c6dc --- /dev/null +++ b/TGC.MonoGame.TP/Content/Models/GermanModel/Skin_metallic.jpeg @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:a23e17776a02a154eb554053dee6590c8bd691b9832f6d477e93c0db267023a3 +size 66163 diff --git a/TGC.MonoGame.TP/Content/Models/GermanModel/Skin_normal.jpeg b/TGC.MonoGame.TP/Content/Models/GermanModel/Skin_normal.jpeg new file mode 100644 index 000000000..c4f081017 --- /dev/null +++ b/TGC.MonoGame.TP/Content/Models/GermanModel/Skin_normal.jpeg @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:44116ccd95d0c716bb686a9a34d1dfe1beda444c35f7bc8bef87ad61b72c3d41 +size 169682 diff --git a/TGC.MonoGame.TP/Content/Models/GermanModel/Skin_roughness.jpeg b/TGC.MonoGame.TP/Content/Models/GermanModel/Skin_roughness.jpeg new file mode 100644 index 000000000..a3b1af05b --- /dev/null +++ b/TGC.MonoGame.TP/Content/Models/GermanModel/Skin_roughness.jpeg @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:2e842b956958e8b0c4d1cddc1c824a8495ca8a691c7ec6b34e13891dae97485d +size 398374 diff --git a/TGC.MonoGame.TP/Content/Models/GermanModel/Wermarcht_AO.jpeg b/TGC.MonoGame.TP/Content/Models/GermanModel/Wermarcht_AO.jpeg new file mode 100644 index 000000000..eafc3ab09 --- /dev/null +++ b/TGC.MonoGame.TP/Content/Models/GermanModel/Wermarcht_AO.jpeg @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:b48e6f3d1f615632ed4f0fe513ff923da10f482080b8ecc98cdd8daee0286ced +size 413810 diff --git a/TGC.MonoGame.TP/Content/Models/GermanModel/Wermarcht_albedo.jpeg b/TGC.MonoGame.TP/Content/Models/GermanModel/Wermarcht_albedo.jpeg new file mode 100644 index 000000000..b57aaccbc --- /dev/null +++ b/TGC.MonoGame.TP/Content/Models/GermanModel/Wermarcht_albedo.jpeg @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:d18ca6cfd64c9ae49df7fe26617aad914650209aaa3f3f6309319d20917ee490 +size 415099 diff --git a/TGC.MonoGame.TP/Content/Models/GermanModel/Wermarcht_metallic.jpeg b/TGC.MonoGame.TP/Content/Models/GermanModel/Wermarcht_metallic.jpeg new file mode 100644 index 000000000..38f24742f --- /dev/null +++ b/TGC.MonoGame.TP/Content/Models/GermanModel/Wermarcht_metallic.jpeg @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:fb1c8e00d3be23921a0ee2aef6b2cabebd8e690aaeaeb5194742e97f1b79026c +size 83465 diff --git a/TGC.MonoGame.TP/Content/Models/GermanModel/Wermarcht_normal.jpeg b/TGC.MonoGame.TP/Content/Models/GermanModel/Wermarcht_normal.jpeg new file mode 100644 index 000000000..4db4a201b --- /dev/null +++ b/TGC.MonoGame.TP/Content/Models/GermanModel/Wermarcht_normal.jpeg @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:1cb4f6f36bc02d682e71ccebf6bf8c40759c28d3ea8780c306633594e754ad74 +size 1393406 diff --git a/TGC.MonoGame.TP/Content/Models/GermanModel/Wermarcht_roughness.jpeg b/TGC.MonoGame.TP/Content/Models/GermanModel/Wermarcht_roughness.jpeg new file mode 100644 index 000000000..8821d82e0 --- /dev/null +++ b/TGC.MonoGame.TP/Content/Models/GermanModel/Wermarcht_roughness.jpeg @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:3d1a99b8d5c1912c5443857760d4d9e13bf2e693cff2ee5a8294fdb0c205ce85 +size 227739 diff --git a/TGC.MonoGame.TP/Content/Models/Grid/ground.x b/TGC.MonoGame.TP/Content/Models/Grid/ground.x new file mode 100644 index 000000000..b343fc092 --- /dev/null +++ b/TGC.MonoGame.TP/Content/Models/Grid/ground.x @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:430d2d274104a9fcce872af2ac108daf5e5792076ce72fb5b9c8fb58b77f8f79 +size 1345 diff --git a/TGC.MonoGame.TP/Content/Models/Grid/terreno.png b/TGC.MonoGame.TP/Content/Models/Grid/terreno.png new file mode 100644 index 000000000..c9d5aac97 --- /dev/null +++ b/TGC.MonoGame.TP/Content/Models/Grid/terreno.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:1aef3442a4085c2eb207dd648a9bd1cd4373c40dd009f8f0a2580b9cb2a08bfe +size 1475581 diff --git a/TGC.MonoGame.TP/Content/Models/M4/Grant_track.dds b/TGC.MonoGame.TP/Content/Models/M4/Grant_track.dds new file mode 100644 index 000000000..6188ffbd4 --- /dev/null +++ b/TGC.MonoGame.TP/Content/Models/M4/Grant_track.dds @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:75cae85a58f8695c561a7473c09a9f17cd2a820ed253c98434a525308c4d4212 +size 87536 diff --git a/TGC.MonoGame.TP/Content/Models/M4/Grant_track_NM.dds b/TGC.MonoGame.TP/Content/Models/M4/Grant_track_NM.dds new file mode 100644 index 000000000..e7e5e9cc2 --- /dev/null +++ b/TGC.MonoGame.TP/Content/Models/M4/Grant_track_NM.dds @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:3876ba963cc8758e5acff463e0e71aa63c9fa670694982da678ed40b39e68aa2 +size 43832 diff --git a/TGC.MonoGame.TP/Content/Models/M4/Grant_track_SM.dds b/TGC.MonoGame.TP/Content/Models/M4/Grant_track_SM.dds new file mode 100644 index 000000000..4c97d6c47 --- /dev/null +++ b/TGC.MonoGame.TP/Content/Models/M4/Grant_track_SM.dds @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:e99bf08054e85c1ee1df7b4a07d257cf7592f069837a5e6e325d39c84ad47772 +size 43832 diff --git a/TGC.MonoGame.TP/Content/Models/M4/M4.fbx b/TGC.MonoGame.TP/Content/Models/M4/M4.fbx new file mode 100644 index 000000000..f591483af --- /dev/null +++ b/TGC.MonoGame.TP/Content/Models/M4/M4.fbx @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:ba35b2dbb54b8a310765b58f8f1abc7b7bbc618db0d6064d497d19fc96facf9b +size 356508 diff --git a/TGC.MonoGame.TP/Content/Models/M4/M4_Sherman.dds b/TGC.MonoGame.TP/Content/Models/M4/M4_Sherman.dds new file mode 100644 index 000000000..136966f37 --- /dev/null +++ b/TGC.MonoGame.TP/Content/Models/M4/M4_Sherman.dds @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:8e68ddd9761b0bae763a799d589c899598fa62ec643adc642f1ec0f54c0c6f4b +size 2796344 diff --git a/TGC.MonoGame.TP/Content/Models/M4/M4_Sherman_NM.dds b/TGC.MonoGame.TP/Content/Models/M4/M4_Sherman_NM.dds new file mode 100644 index 000000000..99026d24e --- /dev/null +++ b/TGC.MonoGame.TP/Content/Models/M4/M4_Sherman_NM.dds @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:adb846fb7112e3c9e10c023a044377fc9b39d38ac5eefd316c0345b31303a5fe +size 2796344 diff --git a/TGC.MonoGame.TP/Content/Models/M4/M4_Sherman_SM.dds b/TGC.MonoGame.TP/Content/Models/M4/M4_Sherman_SM.dds new file mode 100644 index 000000000..bd4b2431f --- /dev/null +++ b/TGC.MonoGame.TP/Content/Models/M4/M4_Sherman_SM.dds @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:40b3f471ee5d090de001d0020c13bbf08c6c0b2eb019bdd5a90fd3c31fc3715c +size 699168 diff --git a/TGC.MonoGame.TP/Content/Models/ModelosVarios/MolinoProp/MolinoProp.fbx b/TGC.MonoGame.TP/Content/Models/ModelosVarios/MolinoProp/MolinoProp.fbx new file mode 100644 index 000000000..dd2e53acc --- /dev/null +++ b/TGC.MonoGame.TP/Content/Models/ModelosVarios/MolinoProp/MolinoProp.fbx @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:e4f2659c8d658c4c845a6dfe5c02fa269c3ad5186eae583f24af4710d2effb16 +size 257884 diff --git a/TGC.MonoGame.TP/Content/Models/ModelosVarios/MolinoProp/T_AmericanPostBox_D.png b/TGC.MonoGame.TP/Content/Models/ModelosVarios/MolinoProp/T_AmericanPostBox_D.png new file mode 100644 index 000000000..c3b608642 --- /dev/null +++ b/TGC.MonoGame.TP/Content/Models/ModelosVarios/MolinoProp/T_AmericanPostBox_D.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:0dc23e772daae9db94a07e92853ad99150cd161f341c2dba01a22e51713ecf99 +size 388030 diff --git a/TGC.MonoGame.TP/Content/Models/ModelosVarios/MolinoProp/T_BMX_D.png b/TGC.MonoGame.TP/Content/Models/ModelosVarios/MolinoProp/T_BMX_D.png new file mode 100644 index 000000000..d17bb1292 --- /dev/null +++ b/TGC.MonoGame.TP/Content/Models/ModelosVarios/MolinoProp/T_BMX_D.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:7d3fc2ef26db5dffb588dd8bb6675306f131802e59a9246fd8ec34bd8fd65386 +size 1103587 diff --git a/TGC.MonoGame.TP/Content/Models/ModelosVarios/MolinoProp/T_BMX_O.png b/TGC.MonoGame.TP/Content/Models/ModelosVarios/MolinoProp/T_BMX_O.png new file mode 100644 index 000000000..7d04c9b05 --- /dev/null +++ b/TGC.MonoGame.TP/Content/Models/ModelosVarios/MolinoProp/T_BMX_O.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:aff8602ad38fcaffbbebb5ab972a4333f3d669232b3ad16e0086c3f7551fec34 +size 21656 diff --git a/TGC.MonoGame.TP/Content/Models/ModelosVarios/MolinoProp/T_Chainfence_D.png b/TGC.MonoGame.TP/Content/Models/ModelosVarios/MolinoProp/T_Chainfence_D.png new file mode 100644 index 000000000..7d9155ed0 --- /dev/null +++ b/TGC.MonoGame.TP/Content/Models/ModelosVarios/MolinoProp/T_Chainfence_D.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:4cce9200bd81504407e4f9ec0b72b86f700f83798d8edcc1ca4eac27248cdba0 +size 194600 diff --git a/TGC.MonoGame.TP/Content/Models/ModelosVarios/MolinoProp/T_Chainfence_O.png b/TGC.MonoGame.TP/Content/Models/ModelosVarios/MolinoProp/T_Chainfence_O.png new file mode 100644 index 000000000..af0e90ef9 --- /dev/null +++ b/TGC.MonoGame.TP/Content/Models/ModelosVarios/MolinoProp/T_Chainfence_O.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:9a661f05047c24d9243636e9a540a941eac7ea684ea2efd4deb2d9e558415563 +size 58191 diff --git a/TGC.MonoGame.TP/Content/Models/ModelosVarios/MolinoProp/T_Lamppost_D.png b/TGC.MonoGame.TP/Content/Models/ModelosVarios/MolinoProp/T_Lamppost_D.png new file mode 100644 index 000000000..284596697 --- /dev/null +++ b/TGC.MonoGame.TP/Content/Models/ModelosVarios/MolinoProp/T_Lamppost_D.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:de06110f1fa3c62ed9640e0bfb76115f39422f3492ae4f04bf49a0844f42a587 +size 1271706 diff --git a/TGC.MonoGame.TP/Content/Models/ModelosVarios/MolinoProp/T_Lamppost_O.png b/TGC.MonoGame.TP/Content/Models/ModelosVarios/MolinoProp/T_Lamppost_O.png new file mode 100644 index 000000000..cb127f7c6 --- /dev/null +++ b/TGC.MonoGame.TP/Content/Models/ModelosVarios/MolinoProp/T_Lamppost_O.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:5ac1b2e2166ca82351d388778c418dac19cc3311dcf313cf22090d63bb5c7e35 +size 3166 diff --git a/TGC.MonoGame.TP/Content/Models/ModelosVarios/MolinoProp/T_Windpump_D.png b/TGC.MonoGame.TP/Content/Models/ModelosVarios/MolinoProp/T_Windpump_D.png new file mode 100644 index 000000000..77b45a854 --- /dev/null +++ b/TGC.MonoGame.TP/Content/Models/ModelosVarios/MolinoProp/T_Windpump_D.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:e702172c89a7d7c82e03728164edf16fd5b1af6d3aba48929b063ecf42b2e715 +size 5299834 diff --git a/TGC.MonoGame.TP/Content/Models/Panzer/Panzer.fbx b/TGC.MonoGame.TP/Content/Models/Panzer/Panzer.fbx new file mode 100644 index 000000000..1e58c319e --- /dev/null +++ b/TGC.MonoGame.TP/Content/Models/Panzer/Panzer.fbx @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:4a3d726f940f104882cbc1e64746366098a13a240d49e533adbe74aceb59afe7 +size 461244 diff --git a/TGC.MonoGame.TP/Content/Models/Panzer/PzVI_Tiger_I_NM.dds b/TGC.MonoGame.TP/Content/Models/Panzer/PzVI_Tiger_I_NM.dds new file mode 100644 index 000000000..ef124f3d5 --- /dev/null +++ b/TGC.MonoGame.TP/Content/Models/Panzer/PzVI_Tiger_I_NM.dds @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:8c65d78a6386f675a37c611aef096880c46f9c77965a61c423f39e88217e5ab6 +size 2796288 diff --git a/TGC.MonoGame.TP/Content/Models/Panzer/PzVI_Tiger_I_SM.dds b/TGC.MonoGame.TP/Content/Models/Panzer/PzVI_Tiger_I_SM.dds new file mode 100644 index 000000000..f826c73bc --- /dev/null +++ b/TGC.MonoGame.TP/Content/Models/Panzer/PzVI_Tiger_I_SM.dds @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:25c5c7d59d1fb74c639302f6c836fc8d1f06a215874208dd65509f5210412639 +size 699168 diff --git a/TGC.MonoGame.TP/Content/Models/Panzer/PzVI_Tiger_I_track.dds b/TGC.MonoGame.TP/Content/Models/Panzer/PzVI_Tiger_I_track.dds new file mode 100644 index 000000000..0125b9f04 --- /dev/null +++ b/TGC.MonoGame.TP/Content/Models/Panzer/PzVI_Tiger_I_track.dds @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:cc3f835845e6a4791127a4a4f950b5dd53ba0b0cb4bc59804360dee673fa8e30 +size 43832 diff --git a/TGC.MonoGame.TP/Content/Models/Panzer/PzVI_Tiger_I_track_NM.dds b/TGC.MonoGame.TP/Content/Models/Panzer/PzVI_Tiger_I_track_NM.dds new file mode 100644 index 000000000..4455a449c --- /dev/null +++ b/TGC.MonoGame.TP/Content/Models/Panzer/PzVI_Tiger_I_track_NM.dds @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:2edd572fd7dfd24afd72b1298ed2acfd4660d531ac501a33f8e845be3494541a +size 43832 diff --git a/TGC.MonoGame.TP/Content/Models/Panzer/PzVI_Tiger_I_track_SM.dds b/TGC.MonoGame.TP/Content/Models/Panzer/PzVI_Tiger_I_track_SM.dds new file mode 100644 index 000000000..c4eb97023 --- /dev/null +++ b/TGC.MonoGame.TP/Content/Models/Panzer/PzVI_Tiger_I_track_SM.dds @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:500a25ed60d3f187ae13c7ccc209ea87d984efe448d66b61ecee84ff15f93eb1 +size 43832 diff --git a/TGC.MonoGame.TP/Content/Models/Panzer/PzVl_Tiger_I.dds b/TGC.MonoGame.TP/Content/Models/Panzer/PzVl_Tiger_I.dds new file mode 100644 index 000000000..d855f661a --- /dev/null +++ b/TGC.MonoGame.TP/Content/Models/Panzer/PzVl_Tiger_I.dds @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:f8ec48ba4ec9c1599d4d819fe8cacabe695ad7488b6b7bad83a903e3ffe3c473 +size 2796344 diff --git a/TGC.MonoGame.TP/Content/Models/Snowy_Shack/Little_shack.fbx b/TGC.MonoGame.TP/Content/Models/Snowy_Shack/Little_shack.fbx new file mode 100644 index 000000000..c43f9309a --- /dev/null +++ b/TGC.MonoGame.TP/Content/Models/Snowy_Shack/Little_shack.fbx @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:5089a7944b2a91d904dbfa570daf42f8c6f04d0e70fda8c45902970f69e34c0e +size 28032 diff --git a/TGC.MonoGame.TP/Content/Models/Snowy_Shack/Little_shack_DefaultMaterial_BaseColor.png b/TGC.MonoGame.TP/Content/Models/Snowy_Shack/Little_shack_DefaultMaterial_BaseColor.png new file mode 100644 index 000000000..67bae55b0 --- /dev/null +++ b/TGC.MonoGame.TP/Content/Models/Snowy_Shack/Little_shack_DefaultMaterial_BaseColor.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:7e38d56666f9bfb0d82662e7496c0bdcab25f8853c28cca1a0087c4a04288a03 +size 5337793 diff --git a/TGC.MonoGame.TP/Content/Models/Snowy_Shack/Little_shack_DefaultMaterial_Height.png b/TGC.MonoGame.TP/Content/Models/Snowy_Shack/Little_shack_DefaultMaterial_Height.png new file mode 100644 index 000000000..22ba3e2d3 --- /dev/null +++ b/TGC.MonoGame.TP/Content/Models/Snowy_Shack/Little_shack_DefaultMaterial_Height.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:c1718d8a817108bae30b1b60f08fcdf8a13befb413eba4798bae09cc76a987ac +size 1270381 diff --git a/TGC.MonoGame.TP/Content/Models/Snowy_Shack/Little_shack_DefaultMaterial_Metallic.png b/TGC.MonoGame.TP/Content/Models/Snowy_Shack/Little_shack_DefaultMaterial_Metallic.png new file mode 100644 index 000000000..0ac75f5cd --- /dev/null +++ b/TGC.MonoGame.TP/Content/Models/Snowy_Shack/Little_shack_DefaultMaterial_Metallic.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:ad48580efc9c9c42b34bede6abfd47ecad454807f37f7f6851e8270fd7805e69 +size 688033 diff --git a/TGC.MonoGame.TP/Content/Models/Snowy_Shack/Little_shack_DefaultMaterial_Normal.png b/TGC.MonoGame.TP/Content/Models/Snowy_Shack/Little_shack_DefaultMaterial_Normal.png new file mode 100644 index 000000000..aba66b94b --- /dev/null +++ b/TGC.MonoGame.TP/Content/Models/Snowy_Shack/Little_shack_DefaultMaterial_Normal.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:fb8b5c0d3a1fcd5cef262f597deebc7c74a1b416942978484a0fdc078d867782 +size 5868471 diff --git a/TGC.MonoGame.TP/Content/Models/Snowy_Shack/Little_shack_DefaultMaterial_Roughness.png b/TGC.MonoGame.TP/Content/Models/Snowy_Shack/Little_shack_DefaultMaterial_Roughness.png new file mode 100644 index 000000000..7a31a558a --- /dev/null +++ b/TGC.MonoGame.TP/Content/Models/Snowy_Shack/Little_shack_DefaultMaterial_Roughness.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:74a73e29f767bfd2445ac1764c3ac2f6799b2c4a02a1e3a9433800d9df6a0665 +size 1031835 diff --git a/TGC.MonoGame.TP/Content/Models/Snowy_Tank/Snowy_Tank.fbx b/TGC.MonoGame.TP/Content/Models/Snowy_Tank/Snowy_Tank.fbx new file mode 100644 index 000000000..d7ea76e5d --- /dev/null +++ b/TGC.MonoGame.TP/Content/Models/Snowy_Tank/Snowy_Tank.fbx @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:0405e01c4e50943293946109efbad648b42600164a88b30c71e121fe832431f8 +size 329548 diff --git a/TGC.MonoGame.TP/Content/Models/Snowy_Tank/water tank_AO.jpg b/TGC.MonoGame.TP/Content/Models/Snowy_Tank/water tank_AO.jpg new file mode 100644 index 000000000..cf7e0cecd --- /dev/null +++ b/TGC.MonoGame.TP/Content/Models/Snowy_Tank/water tank_AO.jpg @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:4fdaf5189f487cca96a3e0cfb27d8c5023a073cb22aecbb848da9a88ba3c6ee8 +size 64629 diff --git a/TGC.MonoGame.TP/Content/Models/Snowy_Tank/water tank_albedo.jpg b/TGC.MonoGame.TP/Content/Models/Snowy_Tank/water tank_albedo.jpg new file mode 100644 index 000000000..7098fcfa6 --- /dev/null +++ b/TGC.MonoGame.TP/Content/Models/Snowy_Tank/water tank_albedo.jpg @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:f683998db29957174f928866c117c76c5bc3f6a7477f1f4a0e16f7f6be3d6ec1 +size 1690539 diff --git a/TGC.MonoGame.TP/Content/Models/Snowy_Tank/water tank_metallic.jpg b/TGC.MonoGame.TP/Content/Models/Snowy_Tank/water tank_metallic.jpg new file mode 100644 index 000000000..670d58cd4 --- /dev/null +++ b/TGC.MonoGame.TP/Content/Models/Snowy_Tank/water tank_metallic.jpg @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:c35ff671a35da9e7baa688a2ee252156a4f5fcd3cb6aa5aba63fd181c9b75432 +size 1999552 diff --git a/TGC.MonoGame.TP/Content/Models/Snowy_Tank/water tank_normal.png b/TGC.MonoGame.TP/Content/Models/Snowy_Tank/water tank_normal.png new file mode 100644 index 000000000..3d7b0aa18 --- /dev/null +++ b/TGC.MonoGame.TP/Content/Models/Snowy_Tank/water tank_normal.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:732b18cc3a295abcbd5735976badf119ec444d97bf7d2e95af8059fa3485eb57 +size 7178056 diff --git a/TGC.MonoGame.TP/Content/Models/Snowy_Tank/water tank_roughness.jpg b/TGC.MonoGame.TP/Content/Models/Snowy_Tank/water tank_roughness.jpg new file mode 100644 index 000000000..9ffe2a166 --- /dev/null +++ b/TGC.MonoGame.TP/Content/Models/Snowy_Tank/water tank_roughness.jpg @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:64762e5ddf936102c86f67f86d888456b561bea6a95dc2f7c0c260379c476a2a +size 1400133 diff --git a/TGC.MonoGame.TP/Content/Models/Stone_House/Roof_col.tga.png b/TGC.MonoGame.TP/Content/Models/Stone_House/Roof_col.tga.png new file mode 100644 index 000000000..8f83e312b --- /dev/null +++ b/TGC.MonoGame.TP/Content/Models/Stone_House/Roof_col.tga.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:fdafd22943cfb44421cb555ac0f1bea90dc5a91a2612da8fb26be6b871a75b11 +size 5315595 diff --git a/TGC.MonoGame.TP/Content/Models/Stone_House/Roof_col_roug.tga.png b/TGC.MonoGame.TP/Content/Models/Stone_House/Roof_col_roug.tga.png new file mode 100644 index 000000000..8a4bcffe2 --- /dev/null +++ b/TGC.MonoGame.TP/Content/Models/Stone_House/Roof_col_roug.tga.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:e4aeb3befe34b4e0ca050829eb3a360842891257ce71cefbccc3db6d53647e5c +size 2426605 diff --git a/TGC.MonoGame.TP/Content/Models/Stone_House/Roof_met.tga.png b/TGC.MonoGame.TP/Content/Models/Stone_House/Roof_met.tga.png new file mode 100644 index 000000000..c1cc9b209 --- /dev/null +++ b/TGC.MonoGame.TP/Content/Models/Stone_House/Roof_met.tga.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:9964cf9090abbc9083e3aecae87a23c53703d2e3b3337bc24be8b467a66e749a +size 2426242 diff --git a/TGC.MonoGame.TP/Content/Models/Stone_House/Roof_norm.tga.png b/TGC.MonoGame.TP/Content/Models/Stone_House/Roof_norm.tga.png new file mode 100644 index 000000000..1e58ae220 --- /dev/null +++ b/TGC.MonoGame.TP/Content/Models/Stone_House/Roof_norm.tga.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:00e7d7da68c5446fd04a3c5d11ada3d59d1706061f8a6b52a6ef074b115d3e82 +size 7664115 diff --git a/TGC.MonoGame.TP/Content/Models/Stone_House/StoneHouse.fbx b/TGC.MonoGame.TP/Content/Models/Stone_House/StoneHouse.fbx new file mode 100644 index 000000000..dc62a74e1 --- /dev/null +++ b/TGC.MonoGame.TP/Content/Models/Stone_House/StoneHouse.fbx @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:353fc781186e9e2fd52ee5f74a9a4e1e24be08d31b46a64a66fcf35bb0364290 +size 7038796 diff --git a/TGC.MonoGame.TP/Content/Models/Stone_House/Wall_col.tga.png b/TGC.MonoGame.TP/Content/Models/Stone_House/Wall_col.tga.png new file mode 100644 index 000000000..6ec4c19f9 --- /dev/null +++ b/TGC.MonoGame.TP/Content/Models/Stone_House/Wall_col.tga.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:ad2f1b4ad104f18f15d830895c1bcac5c52ec5a4f9d8e57ae9e8bf891bdb8b97 +size 5824996 diff --git a/TGC.MonoGame.TP/Content/Models/Stone_House/Wall_met.tga.png b/TGC.MonoGame.TP/Content/Models/Stone_House/Wall_met.tga.png new file mode 100644 index 000000000..4ec53b3e4 --- /dev/null +++ b/TGC.MonoGame.TP/Content/Models/Stone_House/Wall_met.tga.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:5df6d88697c3fa45bdeaa35fcb90a10e45de94e98996e919d3fb08e1c70d56ad +size 1322787 diff --git a/TGC.MonoGame.TP/Content/Models/Stone_House/Wall_norm.tga.png b/TGC.MonoGame.TP/Content/Models/Stone_House/Wall_norm.tga.png new file mode 100644 index 000000000..1d6c8e24e --- /dev/null +++ b/TGC.MonoGame.TP/Content/Models/Stone_House/Wall_norm.tga.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:22903c21f890c59d39e4680ee68e0aa294250469513507432b33263f88b5e516 +size 7927770 diff --git a/TGC.MonoGame.TP/Content/Models/Stone_House/Wall_roug.tga.png b/TGC.MonoGame.TP/Content/Models/Stone_House/Wall_roug.tga.png new file mode 100644 index 000000000..d0d220a8d --- /dev/null +++ b/TGC.MonoGame.TP/Content/Models/Stone_House/Wall_roug.tga.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:b1a3a1572daacbc0292d74d9e89e1e0184a0d4101a22b5102ba6b7d10884cc75 +size 1321440 diff --git a/TGC.MonoGame.TP/Content/Models/Stone_House/Well_ao.tga.png b/TGC.MonoGame.TP/Content/Models/Stone_House/Well_ao.tga.png new file mode 100644 index 000000000..b1c4679aa --- /dev/null +++ b/TGC.MonoGame.TP/Content/Models/Stone_House/Well_ao.tga.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:1d71925e8bf50ac91ccf78e7daf665a89904421cf0efb2bbaa30d5d10c923c8c +size 2893710 diff --git a/TGC.MonoGame.TP/Content/Models/Stone_House/Wood_ao_all.tga.png b/TGC.MonoGame.TP/Content/Models/Stone_House/Wood_ao_all.tga.png new file mode 100644 index 000000000..25e221730 --- /dev/null +++ b/TGC.MonoGame.TP/Content/Models/Stone_House/Wood_ao_all.tga.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:5bc88a399adfc993ea8b48499274ba2b9f9ca83acac1303bbe7ebf7bcc36ece0 +size 3345731 diff --git a/TGC.MonoGame.TP/Content/Models/Stone_House/Wood_col.tga.png b/TGC.MonoGame.TP/Content/Models/Stone_House/Wood_col.tga.png new file mode 100644 index 000000000..1a317a433 --- /dev/null +++ b/TGC.MonoGame.TP/Content/Models/Stone_House/Wood_col.tga.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:b8ed17b07fca0eb32259320f6c4ac3b0bc1d8f7399b672490df13659926092f5 +size 6807805 diff --git a/TGC.MonoGame.TP/Content/Models/Stone_House/Wood_met.tga.png b/TGC.MonoGame.TP/Content/Models/Stone_House/Wood_met.tga.png new file mode 100644 index 000000000..43c6f3789 --- /dev/null +++ b/TGC.MonoGame.TP/Content/Models/Stone_House/Wood_met.tga.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:05f2b66685c4d2c6dcb695696b286f4d2e64a299a3f4dc12af489dcfa8bb0921 +size 3029187 diff --git a/TGC.MonoGame.TP/Content/Models/Stone_House/Wood_norm.tga.png b/TGC.MonoGame.TP/Content/Models/Stone_House/Wood_norm.tga.png new file mode 100644 index 000000000..760e9321d --- /dev/null +++ b/TGC.MonoGame.TP/Content/Models/Stone_House/Wood_norm.tga.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:00906c203bb34d10cdb884329b5d979e7b81d4cc5384c2f47826898adb50b545 +size 7831348 diff --git a/TGC.MonoGame.TP/Content/Models/Stone_House/Wood_rough.tga.png b/TGC.MonoGame.TP/Content/Models/Stone_House/Wood_rough.tga.png new file mode 100644 index 000000000..243f38f09 --- /dev/null +++ b/TGC.MonoGame.TP/Content/Models/Stone_House/Wood_rough.tga.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:95b3ea45ee5659562b23b16d1cdc99019d835e3185208536110cde0aa17ea843 +size 3058445 diff --git a/TGC.MonoGame.TP/Content/Models/Stone_House/roof_ao.tga.png b/TGC.MonoGame.TP/Content/Models/Stone_House/roof_ao.tga.png new file mode 100644 index 000000000..a178f4f3d --- /dev/null +++ b/TGC.MonoGame.TP/Content/Models/Stone_House/roof_ao.tga.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:2636869ae1c0d6c29019dfcffd5ee6214e6678229e60a63e293fd86ed7b65a37 +size 3433417 diff --git a/TGC.MonoGame.TP/Content/Models/Stone_House/wall_mat_ao.tga.png b/TGC.MonoGame.TP/Content/Models/Stone_House/wall_mat_ao.tga.png new file mode 100644 index 000000000..a4c7dc5f8 --- /dev/null +++ b/TGC.MonoGame.TP/Content/Models/Stone_House/wall_mat_ao.tga.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:e32be1b18f197ecece6e6855ae886ab1efdc685868265b686941aa458495cdb5 +size 3250743 diff --git a/TGC.MonoGame.TP/Content/Models/Stone_House/well_col.tga.png b/TGC.MonoGame.TP/Content/Models/Stone_House/well_col.tga.png new file mode 100644 index 000000000..0a504c2da --- /dev/null +++ b/TGC.MonoGame.TP/Content/Models/Stone_House/well_col.tga.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:4bafe9e162a1c1f716c2504fbc332db47a97e1377f3eb50995759303ad3a3514 +size 4829704 diff --git a/TGC.MonoGame.TP/Content/Models/Stone_House/well_met.tga.png b/TGC.MonoGame.TP/Content/Models/Stone_House/well_met.tga.png new file mode 100644 index 000000000..346f55427 --- /dev/null +++ b/TGC.MonoGame.TP/Content/Models/Stone_House/well_met.tga.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:8919624c5d592fa03c0e90c4566c4eb1cba536f01cf7220cec2a300815c92f04 +size 1812111 diff --git a/TGC.MonoGame.TP/Content/Models/Stone_House/well_norm.tga.png b/TGC.MonoGame.TP/Content/Models/Stone_House/well_norm.tga.png new file mode 100644 index 000000000..8ec10f901 --- /dev/null +++ b/TGC.MonoGame.TP/Content/Models/Stone_House/well_norm.tga.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:398b55acc28abfe31c0cbb88a93b7aa7f01413bde8ca360a0334d2eab3164485 +size 7966977 diff --git a/TGC.MonoGame.TP/Content/Models/Stone_House/well_roug.tga.png b/TGC.MonoGame.TP/Content/Models/Stone_House/well_roug.tga.png new file mode 100644 index 000000000..42ddf7a85 --- /dev/null +++ b/TGC.MonoGame.TP/Content/Models/Stone_House/well_roug.tga.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:47a212ed8e82949bfd7097b441aa50b067a1bc0fa88cf47297c0d45283a427c1 +size 1676489 diff --git a/TGC.MonoGame.TP/Content/Models/TankBullets/Apcr.fbx b/TGC.MonoGame.TP/Content/Models/TankBullets/Apcr.fbx new file mode 100644 index 000000000..4e3978e7d --- /dev/null +++ b/TGC.MonoGame.TP/Content/Models/TankBullets/Apcr.fbx @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:51a1129460243aba08531d8302bfbe4b41a05814e6c2a1ed9c2af6a27206f9a0 +size 76988 diff --git a/TGC.MonoGame.TP/Content/Models/TankBullets/ApcrTexture.png b/TGC.MonoGame.TP/Content/Models/TankBullets/ApcrTexture.png new file mode 100644 index 000000000..f08bc2a30 --- /dev/null +++ b/TGC.MonoGame.TP/Content/Models/TankBullets/ApcrTexture.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:d52924fd07d06427113497fbfcf3821884bfb2203d24c69b0dff5703440472de +size 327254 diff --git a/TGC.MonoGame.TP/Content/Models/Terrain/terrain_alpine.fbx b/TGC.MonoGame.TP/Content/Models/Terrain/terrain_alpine.fbx new file mode 100644 index 000000000..6d73d27e1 --- /dev/null +++ b/TGC.MonoGame.TP/Content/Models/Terrain/terrain_alpine.fbx @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:02751bc927add13dd2f511b0577da61907d8612cffe4fd33318017cfa001bdae +size 10720828 diff --git a/TGC.MonoGame.TP/Content/Models/assets militares/Textures/UE/T_rsg_military_antitank_hedgehog_01_AOR.tga b/TGC.MonoGame.TP/Content/Models/assets militares/Textures/UE/T_rsg_military_antitank_hedgehog_01_AOR.tga new file mode 100644 index 000000000..a1343aa1c --- /dev/null +++ b/TGC.MonoGame.TP/Content/Models/assets militares/Textures/UE/T_rsg_military_antitank_hedgehog_01_AOR.tga @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:fd034f39c633ba1d3e38ef2a079fd97b8eb234cc6a564b90c183c6f0992edf19 +size 12582956 diff --git a/TGC.MonoGame.TP/Content/Models/assets militares/Textures/UE/T_rsg_military_antitank_hedgehog_01_BC.tga b/TGC.MonoGame.TP/Content/Models/assets militares/Textures/UE/T_rsg_military_antitank_hedgehog_01_BC.tga new file mode 100644 index 000000000..c5d0e5f0f --- /dev/null +++ b/TGC.MonoGame.TP/Content/Models/assets militares/Textures/UE/T_rsg_military_antitank_hedgehog_01_BC.tga @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:f77d210a143b27db523dff5b05517627121c248cffaba21db73fe9ce2ed83d87 +size 16777260 diff --git a/TGC.MonoGame.TP/Content/Models/assets militares/Textures/UE/T_rsg_military_antitank_hedgehog_01_N.tga b/TGC.MonoGame.TP/Content/Models/assets militares/Textures/UE/T_rsg_military_antitank_hedgehog_01_N.tga new file mode 100644 index 000000000..9a55e2816 --- /dev/null +++ b/TGC.MonoGame.TP/Content/Models/assets militares/Textures/UE/T_rsg_military_antitank_hedgehog_01_N.tga @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:97e1ac51e603bd969d93ac649ed757bfca7f2728a2d288cf2d18a0f5e0a9d265 +size 12582956 diff --git a/TGC.MonoGame.TP/Content/Models/assets militares/Textures/UE/T_rsg_military_concret_block_01_AOR.tga b/TGC.MonoGame.TP/Content/Models/assets militares/Textures/UE/T_rsg_military_concret_block_01_AOR.tga new file mode 100644 index 000000000..fa5fbd350 --- /dev/null +++ b/TGC.MonoGame.TP/Content/Models/assets militares/Textures/UE/T_rsg_military_concret_block_01_AOR.tga @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:6de4aa9abf8d2b69bab8322471a0799688083439e7e28a7974e019218a676a5c +size 12582956 diff --git a/TGC.MonoGame.TP/Content/Models/assets militares/Textures/UE/T_rsg_military_concret_block_01_BC.tga b/TGC.MonoGame.TP/Content/Models/assets militares/Textures/UE/T_rsg_military_concret_block_01_BC.tga new file mode 100644 index 000000000..776c5f2ee --- /dev/null +++ b/TGC.MonoGame.TP/Content/Models/assets militares/Textures/UE/T_rsg_military_concret_block_01_BC.tga @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:5053d39f3b1efe97730f29d4357c689dad272342a5215677ae4e2ea768a6442a +size 12582956 diff --git a/TGC.MonoGame.TP/Content/Models/assets militares/Textures/UE/T_rsg_military_concret_block_01_N.tga b/TGC.MonoGame.TP/Content/Models/assets militares/Textures/UE/T_rsg_military_concret_block_01_N.tga new file mode 100644 index 000000000..875afb23c --- /dev/null +++ b/TGC.MonoGame.TP/Content/Models/assets militares/Textures/UE/T_rsg_military_concret_block_01_N.tga @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:8d926a99435692770829249fdd51ef75ddf3e09818818b8f0ff7b45e0cd85d97 +size 12582956 diff --git a/TGC.MonoGame.TP/Content/Models/assets militares/Textures/UE/T_rsg_military_sandbox_01_AOR.tga b/TGC.MonoGame.TP/Content/Models/assets militares/Textures/UE/T_rsg_military_sandbox_01_AOR.tga new file mode 100644 index 000000000..5b7b5e188 --- /dev/null +++ b/TGC.MonoGame.TP/Content/Models/assets militares/Textures/UE/T_rsg_military_sandbox_01_AOR.tga @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:eabb6fa0180a6fba22b851ccc3341954ab89bbb003094d7f8df94cbd981e023b +size 25165868 diff --git a/TGC.MonoGame.TP/Content/Models/assets militares/Textures/UE/T_rsg_military_sandbox_01_BC.tga b/TGC.MonoGame.TP/Content/Models/assets militares/Textures/UE/T_rsg_military_sandbox_01_BC.tga new file mode 100644 index 000000000..ad5aac78b --- /dev/null +++ b/TGC.MonoGame.TP/Content/Models/assets militares/Textures/UE/T_rsg_military_sandbox_01_BC.tga @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:3845fd6f5adf027a81a1b2ea7dced7828c23b3bd700bbf783d3f087530ffafd3 +size 25165868 diff --git a/TGC.MonoGame.TP/Content/Models/assets militares/Textures/UE/T_rsg_military_sandbox_01_N.tga b/TGC.MonoGame.TP/Content/Models/assets militares/Textures/UE/T_rsg_military_sandbox_01_N.tga new file mode 100644 index 000000000..fb5b74def --- /dev/null +++ b/TGC.MonoGame.TP/Content/Models/assets militares/Textures/UE/T_rsg_military_sandbox_01_N.tga @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:d0f1ff1a4b4956d918d51a63887f2cf7f2af3feda4abaaaae69ba5c459259b9f +size 25165868 diff --git a/TGC.MonoGame.TP/Content/Models/assets militares/Textures/Unity/T_rsg_military_antitank_hedgehog_01_AOR.tga b/TGC.MonoGame.TP/Content/Models/assets militares/Textures/Unity/T_rsg_military_antitank_hedgehog_01_AOR.tga new file mode 100644 index 000000000..6f3a1435e --- /dev/null +++ b/TGC.MonoGame.TP/Content/Models/assets militares/Textures/Unity/T_rsg_military_antitank_hedgehog_01_AOR.tga @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:56b11fef9701a159a85a76452e860bd7ee2e9c848b1b564b03ff6ca992fd6245 +size 16777260 diff --git a/TGC.MonoGame.TP/Content/Models/assets militares/Textures/Unity/T_rsg_military_antitank_hedgehog_01_BC.tga b/TGC.MonoGame.TP/Content/Models/assets militares/Textures/Unity/T_rsg_military_antitank_hedgehog_01_BC.tga new file mode 100644 index 000000000..c5d0e5f0f --- /dev/null +++ b/TGC.MonoGame.TP/Content/Models/assets militares/Textures/Unity/T_rsg_military_antitank_hedgehog_01_BC.tga @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:f77d210a143b27db523dff5b05517627121c248cffaba21db73fe9ce2ed83d87 +size 16777260 diff --git a/TGC.MonoGame.TP/Content/Models/assets militares/Textures/Unity/T_rsg_military_antitank_hedgehog_01_N.tga b/TGC.MonoGame.TP/Content/Models/assets militares/Textures/Unity/T_rsg_military_antitank_hedgehog_01_N.tga new file mode 100644 index 000000000..b51422383 --- /dev/null +++ b/TGC.MonoGame.TP/Content/Models/assets militares/Textures/Unity/T_rsg_military_antitank_hedgehog_01_N.tga @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:dba4b701e7040c3a2dd9f942061d6c5045ae6861ee39537c4e16809ddb6cf35a +size 16777260 diff --git a/TGC.MonoGame.TP/Content/Models/assets militares/Textures/Unity/T_rsg_military_concret_block_01_AOR.tga b/TGC.MonoGame.TP/Content/Models/assets militares/Textures/Unity/T_rsg_military_concret_block_01_AOR.tga new file mode 100644 index 000000000..e9fe9aca1 --- /dev/null +++ b/TGC.MonoGame.TP/Content/Models/assets militares/Textures/Unity/T_rsg_military_concret_block_01_AOR.tga @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:31f279a80768c915113cd76abef6f1516220a7a5568b7c09bcf9e0cff0ebff27 +size 16777260 diff --git a/TGC.MonoGame.TP/Content/Models/assets militares/Textures/Unity/T_rsg_military_concret_block_01_BC.tga b/TGC.MonoGame.TP/Content/Models/assets militares/Textures/Unity/T_rsg_military_concret_block_01_BC.tga new file mode 100644 index 000000000..776c5f2ee --- /dev/null +++ b/TGC.MonoGame.TP/Content/Models/assets militares/Textures/Unity/T_rsg_military_concret_block_01_BC.tga @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:5053d39f3b1efe97730f29d4357c689dad272342a5215677ae4e2ea768a6442a +size 12582956 diff --git a/TGC.MonoGame.TP/Content/Models/assets militares/Textures/Unity/T_rsg_military_concret_block_01_N.tga b/TGC.MonoGame.TP/Content/Models/assets militares/Textures/Unity/T_rsg_military_concret_block_01_N.tga new file mode 100644 index 000000000..ce6fee183 --- /dev/null +++ b/TGC.MonoGame.TP/Content/Models/assets militares/Textures/Unity/T_rsg_military_concret_block_01_N.tga @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:65eb94321399dba0a401d65b45199982a7acfbf7d19a4daf7d5107864cadb7a1 +size 12582956 diff --git a/TGC.MonoGame.TP/Content/Models/assets militares/Textures/Unity/T_rsg_military_sandbox_01_AOR.tga b/TGC.MonoGame.TP/Content/Models/assets militares/Textures/Unity/T_rsg_military_sandbox_01_AOR.tga new file mode 100644 index 000000000..0c8957e23 --- /dev/null +++ b/TGC.MonoGame.TP/Content/Models/assets militares/Textures/Unity/T_rsg_military_sandbox_01_AOR.tga @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:f1630a15ddf5caa4e5658ad841c47985d87ef8d9bc8272f74f16eac99e4a3af6 +size 33554476 diff --git a/TGC.MonoGame.TP/Content/Models/assets militares/Textures/Unity/T_rsg_military_sandbox_01_BC.tga b/TGC.MonoGame.TP/Content/Models/assets militares/Textures/Unity/T_rsg_military_sandbox_01_BC.tga new file mode 100644 index 000000000..ad5aac78b --- /dev/null +++ b/TGC.MonoGame.TP/Content/Models/assets militares/Textures/Unity/T_rsg_military_sandbox_01_BC.tga @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:3845fd6f5adf027a81a1b2ea7dced7828c23b3bd700bbf783d3f087530ffafd3 +size 25165868 diff --git a/TGC.MonoGame.TP/Content/Models/assets militares/Textures/Unity/T_rsg_military_sandbox_01_N.tga b/TGC.MonoGame.TP/Content/Models/assets militares/Textures/Unity/T_rsg_military_sandbox_01_N.tga new file mode 100644 index 000000000..fb5b74def --- /dev/null +++ b/TGC.MonoGame.TP/Content/Models/assets militares/Textures/Unity/T_rsg_military_sandbox_01_N.tga @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:d0f1ff1a4b4956d918d51a63887f2cf7f2af3feda4abaaaae69ba5c459259b9f +size 25165868 diff --git a/TGC.MonoGame.TP/Content/Models/assets militares/rsg_military_antitank_hedgehog_01.fbx b/TGC.MonoGame.TP/Content/Models/assets militares/rsg_military_antitank_hedgehog_01.fbx new file mode 100644 index 000000000..9ce7d07a8 --- /dev/null +++ b/TGC.MonoGame.TP/Content/Models/assets militares/rsg_military_antitank_hedgehog_01.fbx @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:208aa63f6c3bd0e7cd1d5be6047b80f0385a60835e93b537adc79e9f430369c9 +size 90192 diff --git a/TGC.MonoGame.TP/Content/Models/assets militares/rsg_military_barbed_wire_01.fbx b/TGC.MonoGame.TP/Content/Models/assets militares/rsg_military_barbed_wire_01.fbx new file mode 100644 index 000000000..3da7ba531 --- /dev/null +++ b/TGC.MonoGame.TP/Content/Models/assets militares/rsg_military_barbed_wire_01.fbx @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:c7d38b5807f2ca5d32329a563e59d49bb9d46c92ffc3f438d5bac2582dfebbd2 +size 63152 diff --git a/TGC.MonoGame.TP/Content/Models/assets militares/rsg_military_concret-block_01.fbx b/TGC.MonoGame.TP/Content/Models/assets militares/rsg_military_concret-block_01.fbx new file mode 100644 index 000000000..070c1f837 --- /dev/null +++ b/TGC.MonoGame.TP/Content/Models/assets militares/rsg_military_concret-block_01.fbx @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:e652da221dc04a5d4b6beed8a02c750bee4366bd3cf02b0b32bb5f1d581656ff +size 63056 diff --git a/TGC.MonoGame.TP/Content/Models/assets militares/rsg_military_sandbox_01.fbx b/TGC.MonoGame.TP/Content/Models/assets militares/rsg_military_sandbox_01.fbx new file mode 100644 index 000000000..e89447450 --- /dev/null +++ b/TGC.MonoGame.TP/Content/Models/assets militares/rsg_military_sandbox_01.fbx @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:6e9402f35132d32d4621260170e8c302bf11cde0e3a6e723cb07eed0524aea2b +size 375216 diff --git a/TGC.MonoGame.TP/Content/Models/casa/Medieval_Brick_Texture_by_goodtextures.jpg b/TGC.MonoGame.TP/Content/Models/casa/Medieval_Brick_Texture_by_goodtextures.jpg new file mode 100644 index 000000000..7f9adad40 --- /dev/null +++ b/TGC.MonoGame.TP/Content/Models/casa/Medieval_Brick_Texture_by_goodtextures.jpg @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:1b74eb37fb39d237c26cbf0f635eaa0b4553f1f96df8346a9a3ed69fd55988ec +size 308687 diff --git a/TGC.MonoGame.TP/Content/Models/casa/WoodPlanksBare0051_3_M.jpg b/TGC.MonoGame.TP/Content/Models/casa/WoodPlanksBare0051_3_M.jpg new file mode 100644 index 000000000..7aa9c027f --- /dev/null +++ b/TGC.MonoGame.TP/Content/Models/casa/WoodPlanksBare0051_3_M.jpg @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:a4b9ceb5048596acc5cd109183763c533ed15f716a300d81afaf0c10b289fbbf +size 582794 diff --git a/TGC.MonoGame.TP/Content/Models/casa/house.fbx b/TGC.MonoGame.TP/Content/Models/casa/house.fbx new file mode 100644 index 000000000..3a1702bfb --- /dev/null +++ b/TGC.MonoGame.TP/Content/Models/casa/house.fbx @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:90fba72bc3c722581ab554cac9c0fe0737d84e5ddd71ae7b4fadab09ac649b69 +size 53324 diff --git a/TGC.MonoGame.TP/Content/Models/casa/windows_0279_01_preview.jpg b/TGC.MonoGame.TP/Content/Models/casa/windows_0279_01_preview.jpg new file mode 100644 index 000000000..0af68c1f0 --- /dev/null +++ b/TGC.MonoGame.TP/Content/Models/casa/windows_0279_01_preview.jpg @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:099e4c0af76f79ce45d5b987e62f8fa7959a57b62f6763269e699d6d9c390c69 +size 65053 diff --git a/TGC.MonoGame.TP/Content/Models/cube.fbx b/TGC.MonoGame.TP/Content/Models/cube.fbx new file mode 100644 index 000000000..a2de74f05 --- /dev/null +++ b/TGC.MonoGame.TP/Content/Models/cube.fbx @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:fd80f2f0d3ded3a1dccd83450fe771f19697436e342ed9fc3b0a8797a5c9dc1c +size 10535 diff --git a/TGC.MonoGame.TP/Content/Models/grass/grassAlphaMapped.png b/TGC.MonoGame.TP/Content/Models/grass/grassAlphaMapped.png new file mode 100644 index 000000000..8782d8318 --- /dev/null +++ b/TGC.MonoGame.TP/Content/Models/grass/grassAlphaMapped.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:c0a3a1180698ad9399e7231d2fe85660bf361ce7e94452f59d2a2ff167b9df54 +size 1053734 diff --git a/TGC.MonoGame.TP/Content/Models/grass/grassNormal.png b/TGC.MonoGame.TP/Content/Models/grass/grassNormal.png new file mode 100644 index 000000000..bf92f4b09 --- /dev/null +++ b/TGC.MonoGame.TP/Content/Models/grass/grassNormal.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:7e0eedf5b4c6dc106187dde36f5373a74c7d43ffd52a03b4b83a76c9a022f558 +size 1069315 diff --git a/TGC.MonoGame.TP/Content/Models/grass/grassSmoothness.png b/TGC.MonoGame.TP/Content/Models/grass/grassSmoothness.png new file mode 100644 index 000000000..724ed4e57 --- /dev/null +++ b/TGC.MonoGame.TP/Content/Models/grass/grassSmoothness.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:0ac03ce82f78762dc283adbad397d04f95853e5e49d2fbb875afa33594e6b36a +size 1135832 diff --git a/TGC.MonoGame.TP/Content/Models/grass/grasscolor.png b/TGC.MonoGame.TP/Content/Models/grass/grasscolor.png new file mode 100644 index 000000000..50ff3f425 --- /dev/null +++ b/TGC.MonoGame.TP/Content/Models/grass/grasscolor.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:22a127d7cd66cc41011bcf825ea56f291d03a60ed6b49f03ee9f1ffa6ae860cd +size 2040973 diff --git a/TGC.MonoGame.TP/Content/Models/grass/grasspatches.fbx b/TGC.MonoGame.TP/Content/Models/grass/grasspatches.fbx new file mode 100644 index 000000000..f78588fbb --- /dev/null +++ b/TGC.MonoGame.TP/Content/Models/grass/grasspatches.fbx @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:bc110e99ae2bfb42ffccdd8aa010bf01d699f5cc849caa337ef76e5211b6d093 +size 112876 diff --git a/TGC.MonoGame.TP/Content/Models/nature/rock/Rock_1.fbx b/TGC.MonoGame.TP/Content/Models/nature/rock/Rock_1.fbx new file mode 100644 index 000000000..b4861f62e --- /dev/null +++ b/TGC.MonoGame.TP/Content/Models/nature/rock/Rock_1.fbx @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:00dda3f20f960325ac77671f72a2b80f822de352107cd40d056f68ff9f46438f +size 78492 diff --git a/TGC.MonoGame.TP/Content/Models/nature/rock/Rock_1_Glossiness.jpg b/TGC.MonoGame.TP/Content/Models/nature/rock/Rock_1_Glossiness.jpg new file mode 100644 index 000000000..4a62cf6ce --- /dev/null +++ b/TGC.MonoGame.TP/Content/Models/nature/rock/Rock_1_Glossiness.jpg @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:15b15afe7bfe70c2a98ada3643e3f2a4ae7ab45453642e90ed7bf7c59a19190b +size 1577267 diff --git a/TGC.MonoGame.TP/Content/Models/nature/rock/Rock_1_Normal.jpg b/TGC.MonoGame.TP/Content/Models/nature/rock/Rock_1_Normal.jpg new file mode 100644 index 000000000..34e35f2b6 --- /dev/null +++ b/TGC.MonoGame.TP/Content/Models/nature/rock/Rock_1_Normal.jpg @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:0ac0f9cc5b0da2807916c206d9245b85410c1abe361c0b72afb55253c038305e +size 1809864 diff --git a/TGC.MonoGame.TP/Content/Models/nature/rock/Rock_1_Specular.jpg b/TGC.MonoGame.TP/Content/Models/nature/rock/Rock_1_Specular.jpg new file mode 100644 index 000000000..579ce4a5f --- /dev/null +++ b/TGC.MonoGame.TP/Content/Models/nature/rock/Rock_1_Specular.jpg @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:2f3a9b82888d6001f42732c5ef01b001e44c72b9eacbc7979ac34929a189391c +size 73281 diff --git a/TGC.MonoGame.TP/Content/Models/nature/rock/Rock_1_occlusion.jpg b/TGC.MonoGame.TP/Content/Models/nature/rock/Rock_1_occlusion.jpg new file mode 100644 index 000000000..fcc69b175 --- /dev/null +++ b/TGC.MonoGame.TP/Content/Models/nature/rock/Rock_1_occlusion.jpg @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:b75c061e050699cb6c394ad95c501580e12215010c16f0c5c7269fb610c4cc21 +size 1449941 diff --git "a/TGC.MonoGame.TP/Content/Models/nature/rock/Yeni klas\303\266r/Rock_1_Base_Color.jpg" "b/TGC.MonoGame.TP/Content/Models/nature/rock/Yeni klas\303\266r/Rock_1_Base_Color.jpg" new file mode 100644 index 000000000..d4229e174 --- /dev/null +++ "b/TGC.MonoGame.TP/Content/Models/nature/rock/Yeni klas\303\266r/Rock_1_Base_Color.jpg" @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:66c02c215a489f66d99d1eef66ddcea21dff1ddc38ca6d59edd876f780899134 +size 571470 diff --git a/TGC.MonoGame.TP/Content/Models/skybox/cube.fbx b/TGC.MonoGame.TP/Content/Models/skybox/cube.fbx new file mode 100644 index 000000000..a2de74f05 --- /dev/null +++ b/TGC.MonoGame.TP/Content/Models/skybox/cube.fbx @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:fd80f2f0d3ded3a1dccd83450fe771f19697436e342ed9fc3b0a8797a5c9dc1c +size 10535 diff --git a/TGC.MonoGame.TP/Content/Models/tgc-logo/tgc-logo.fbx b/TGC.MonoGame.TP/Content/Models/tgc-logo/tgc-logo.fbx deleted file mode 100644 index 6f066d809..000000000 --- a/TGC.MonoGame.TP/Content/Models/tgc-logo/tgc-logo.fbx +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:af84a6d4a433db8f49c3895d534e37aacddf68b27f9611856e76a6052562fe3f -size 4751036 diff --git a/TGC.MonoGame.TP/Content/Music/TankGameBackgroundSound.mp3 b/TGC.MonoGame.TP/Content/Music/TankGameBackgroundSound.mp3 new file mode 100644 index 000000000..d9ce32642 --- /dev/null +++ b/TGC.MonoGame.TP/Content/Music/TankGameBackgroundSound.mp3 @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:891cecbdc524406587968a835420d0c6e444a3e38f3844516f49e5f940ee98eb +size 57600815 diff --git a/TGC.MonoGame.TP/Content/Music/movingTank.mp3 b/TGC.MonoGame.TP/Content/Music/movingTank.mp3 new file mode 100644 index 000000000..e328019be --- /dev/null +++ b/TGC.MonoGame.TP/Content/Music/movingTank.mp3 @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:dc0ac08eafec09b82f27938eb171f156d03c0c0064f9fc9b82550355f3e77378 +size 2110511 diff --git a/TGC.MonoGame.TP/Content/Music/shootSound.mp3 b/TGC.MonoGame.TP/Content/Music/shootSound.mp3 new file mode 100644 index 000000000..2d55abb45 --- /dev/null +++ b/TGC.MonoGame.TP/Content/Music/shootSound.mp3 @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:fed5fdf1e00c906e531d3eed5f57b11d3ea54e1cd4635e5764c5c734e7153c63 +size 29967 diff --git a/TGC.MonoGame.TP/Content/Textures/HUD/lifebar.png b/TGC.MonoGame.TP/Content/Textures/HUD/lifebar.png new file mode 100644 index 000000000..90debd252 --- /dev/null +++ b/TGC.MonoGame.TP/Content/Textures/HUD/lifebar.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:f48b61d81f1f94326fa846e35e30545b66fa1eb876d3b4c328e9edf9bd874393 +size 2077 diff --git a/TGC.MonoGame.TP/Content/Textures/HUD/lifebar/1.png b/TGC.MonoGame.TP/Content/Textures/HUD/lifebar/1.png new file mode 100644 index 000000000..3e1c4cc7d --- /dev/null +++ b/TGC.MonoGame.TP/Content/Textures/HUD/lifebar/1.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:bd923b4aa52f838bfa9b8c8b756ca076614c1697b46db67e6074866dd24be6f0 +size 725 diff --git a/TGC.MonoGame.TP/Content/Textures/HUD/lifebar/10.png b/TGC.MonoGame.TP/Content/Textures/HUD/lifebar/10.png new file mode 100644 index 000000000..372852c70 --- /dev/null +++ b/TGC.MonoGame.TP/Content/Textures/HUD/lifebar/10.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:b1c78b89d1f6a91274f87e261a1f12039fef0c4535584eb13515fbce613c7ced +size 381 diff --git a/TGC.MonoGame.TP/Content/Textures/HUD/lifebar/11.png b/TGC.MonoGame.TP/Content/Textures/HUD/lifebar/11.png new file mode 100644 index 000000000..30d9eef40 --- /dev/null +++ b/TGC.MonoGame.TP/Content/Textures/HUD/lifebar/11.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:aca2c324efb8705315ed2ea3b13bb917087a118a41cf3ffe710fe368491e4b07 +size 381 diff --git a/TGC.MonoGame.TP/Content/Textures/HUD/lifebar/2.png b/TGC.MonoGame.TP/Content/Textures/HUD/lifebar/2.png new file mode 100644 index 000000000..26c698bec --- /dev/null +++ b/TGC.MonoGame.TP/Content/Textures/HUD/lifebar/2.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:47d34cd2f1947edbf569b1b9d1e1c9c67ea58b9aa9fc7fe5e96e3d8ce5a9b99b +size 688 diff --git a/TGC.MonoGame.TP/Content/Textures/HUD/lifebar/3.png b/TGC.MonoGame.TP/Content/Textures/HUD/lifebar/3.png new file mode 100644 index 000000000..5877af14a --- /dev/null +++ b/TGC.MonoGame.TP/Content/Textures/HUD/lifebar/3.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:7a6482f743eb0824d43479a420aebe2d06b3bc9d777b8306a3afc4994d035df4 +size 653 diff --git a/TGC.MonoGame.TP/Content/Textures/HUD/lifebar/4.png b/TGC.MonoGame.TP/Content/Textures/HUD/lifebar/4.png new file mode 100644 index 000000000..64e07050c --- /dev/null +++ b/TGC.MonoGame.TP/Content/Textures/HUD/lifebar/4.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:61bf43c0a0740642a2b0bf8d6cbb8065a02686e667498d6d39205279c572c97b +size 628 diff --git a/TGC.MonoGame.TP/Content/Textures/HUD/lifebar/5.png b/TGC.MonoGame.TP/Content/Textures/HUD/lifebar/5.png new file mode 100644 index 000000000..44d60086b --- /dev/null +++ b/TGC.MonoGame.TP/Content/Textures/HUD/lifebar/5.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:485552bec47f06328a6be26450471ff5527736e48f4efec558816d2fc3409ecc +size 594 diff --git a/TGC.MonoGame.TP/Content/Textures/HUD/lifebar/6.png b/TGC.MonoGame.TP/Content/Textures/HUD/lifebar/6.png new file mode 100644 index 000000000..b5ce240a1 --- /dev/null +++ b/TGC.MonoGame.TP/Content/Textures/HUD/lifebar/6.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:50cac75a23697bf303525cda1cf014fdbe759534946a425f50bb883d710490d2 +size 554 diff --git a/TGC.MonoGame.TP/Content/Textures/HUD/lifebar/7.png b/TGC.MonoGame.TP/Content/Textures/HUD/lifebar/7.png new file mode 100644 index 000000000..4a282ab99 --- /dev/null +++ b/TGC.MonoGame.TP/Content/Textures/HUD/lifebar/7.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:dc89a2ce680ef8bc5babdd28c78f3160a43c6c4af2131fefd5e70e92ad38150a +size 518 diff --git a/TGC.MonoGame.TP/Content/Textures/HUD/lifebar/8.png b/TGC.MonoGame.TP/Content/Textures/HUD/lifebar/8.png new file mode 100644 index 000000000..0e528bb0c --- /dev/null +++ b/TGC.MonoGame.TP/Content/Textures/HUD/lifebar/8.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:f49e20380b70378c37436ba597f19b6446674403cae5fde8bd667f0508b34a60 +size 474 diff --git a/TGC.MonoGame.TP/Content/Textures/HUD/lifebar/9.png b/TGC.MonoGame.TP/Content/Textures/HUD/lifebar/9.png new file mode 100644 index 000000000..cf634893f --- /dev/null +++ b/TGC.MonoGame.TP/Content/Textures/HUD/lifebar/9.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:e9611a22882d1810e75b3d6c8e9da0b05e9627409e395f8adc870b1905419ded +size 423 diff --git a/TGC.MonoGame.TP/Content/Textures/HUD/lifebar_empty.png b/TGC.MonoGame.TP/Content/Textures/HUD/lifebar_empty.png new file mode 100644 index 000000000..972e4827c --- /dev/null +++ b/TGC.MonoGame.TP/Content/Textures/HUD/lifebar_empty.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:643cd638e672a31e491c78ab33e24fa8d5a72ff50467ca4cc457e30798773f2e +size 1379 diff --git a/TGC.MonoGame.TP/Content/Textures/Menu/Default@4x.png b/TGC.MonoGame.TP/Content/Textures/Menu/Default@4x.png new file mode 100644 index 000000000..c493ab01c --- /dev/null +++ b/TGC.MonoGame.TP/Content/Textures/Menu/Default@4x.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:15b5419b682e4ab898b1840112754d5b0d0ba2da2d807f0cbb85e9fb5af15258 +size 35525 diff --git a/TGC.MonoGame.TP/Content/Textures/Menu/PlayButton.png b/TGC.MonoGame.TP/Content/Textures/Menu/PlayButton.png new file mode 100644 index 000000000..4240fd6ec --- /dev/null +++ b/TGC.MonoGame.TP/Content/Textures/Menu/PlayButton.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:32e8b46a2991042c8283f24d371b22aca9ff3e6e1aa370a8dafb4b5d83a96146 +size 36483 diff --git a/TGC.MonoGame.TP/Content/Textures/Menu/PlayButtonHover.png b/TGC.MonoGame.TP/Content/Textures/Menu/PlayButtonHover.png new file mode 100644 index 000000000..d53331dff --- /dev/null +++ b/TGC.MonoGame.TP/Content/Textures/Menu/PlayButtonHover.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:970e9e20876f3d7255bc5a6fe057646b62a629a71691aa78e12d877e6d626cc5 +size 30042 diff --git a/TGC.MonoGame.TP/Content/Textures/Menu/RectangleButtonHover.png b/TGC.MonoGame.TP/Content/Textures/Menu/RectangleButtonHover.png new file mode 100644 index 000000000..ecb14d1c6 --- /dev/null +++ b/TGC.MonoGame.TP/Content/Textures/Menu/RectangleButtonHover.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:bce273e3e32b56f083ded84fc84e2bd9ba9f2cb9c650613af33ecb081b476c04 +size 28409 diff --git a/TGC.MonoGame.TP/Content/Textures/Menu/SoundOff.png b/TGC.MonoGame.TP/Content/Textures/Menu/SoundOff.png new file mode 100644 index 000000000..90ceddc6a --- /dev/null +++ b/TGC.MonoGame.TP/Content/Textures/Menu/SoundOff.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:c3edb461efa02c7778fba2437472c7b303d129fa2b2a7c4276560d0f55794600 +size 21283 diff --git a/TGC.MonoGame.TP/Content/Textures/Menu/SoundOffHover.png b/TGC.MonoGame.TP/Content/Textures/Menu/SoundOffHover.png new file mode 100644 index 000000000..2eb273c4d --- /dev/null +++ b/TGC.MonoGame.TP/Content/Textures/Menu/SoundOffHover.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:ff46fd8f580917a72cb515185b721d99e153072f75c3f8096178921083ef8ad0 +size 18656 diff --git a/TGC.MonoGame.TP/Content/Textures/Menu/SoundOn.png b/TGC.MonoGame.TP/Content/Textures/Menu/SoundOn.png new file mode 100644 index 000000000..e9b26cb75 --- /dev/null +++ b/TGC.MonoGame.TP/Content/Textures/Menu/SoundOn.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:b87625c99c8fa2ea5fb7258157c199f3f4080041d5ec45afc789697e5f8c3015 +size 21239 diff --git a/TGC.MonoGame.TP/Content/Textures/Menu/SoundOnHover.png b/TGC.MonoGame.TP/Content/Textures/Menu/SoundOnHover.png new file mode 100644 index 000000000..4c387a358 --- /dev/null +++ b/TGC.MonoGame.TP/Content/Textures/Menu/SoundOnHover.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:7560343818e19f16b55c7cf19d78df2aaa45e6fe81bd49a5a780aa2f6416c98b +size 18482 diff --git a/TGC.MonoGame.TP/Content/Textures/Particulas/0049.png b/TGC.MonoGame.TP/Content/Textures/Particulas/0049.png new file mode 100644 index 000000000..6dcca60fa --- /dev/null +++ b/TGC.MonoGame.TP/Content/Textures/Particulas/0049.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:43705fb4faa0fda82f7158396f57485dad6e98036829be69561738aa4dae916d +size 68752 diff --git a/TGC.MonoGame.TP/Content/Textures/Terrain/alpine_terrain_2k_color.png b/TGC.MonoGame.TP/Content/Textures/Terrain/alpine_terrain_2k_color.png new file mode 100644 index 000000000..4d3b08bf3 --- /dev/null +++ b/TGC.MonoGame.TP/Content/Textures/Terrain/alpine_terrain_2k_color.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:99b8169d1b22eaa9c41a08825d348be8f0f56c4485d235e487e57d2d5aa37a8a +size 8762185 diff --git a/TGC.MonoGame.TP/Content/Textures/Terrain/playaround_3_normal_2k.png b/TGC.MonoGame.TP/Content/Textures/Terrain/playaround_3_normal_2k.png new file mode 100644 index 000000000..07ffaa4ec --- /dev/null +++ b/TGC.MonoGame.TP/Content/Textures/Terrain/playaround_3_normal_2k.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:cb52c3431d6603a01fad6c48c7a9934f5a93a530ebdffae840fc58274ecd7100 +size 9044618 diff --git a/TGC.MonoGame.TP/Content/Textures/casaAbandonada/Medieval_Brick_Texture_by_goodtextures.jpg b/TGC.MonoGame.TP/Content/Textures/casaAbandonada/Medieval_Brick_Texture_by_goodtextures.jpg new file mode 100644 index 000000000..7f9adad40 --- /dev/null +++ b/TGC.MonoGame.TP/Content/Textures/casaAbandonada/Medieval_Brick_Texture_by_goodtextures.jpg @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:1b74eb37fb39d237c26cbf0f635eaa0b4553f1f96df8346a9a3ed69fd55988ec +size 308687 diff --git a/TGC.MonoGame.TP/Content/Textures/casaAbandonada/WoodPlanksBare0051_3_M.jpg b/TGC.MonoGame.TP/Content/Textures/casaAbandonada/WoodPlanksBare0051_3_M.jpg new file mode 100644 index 000000000..7aa9c027f --- /dev/null +++ b/TGC.MonoGame.TP/Content/Textures/casaAbandonada/WoodPlanksBare0051_3_M.jpg @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:a4b9ceb5048596acc5cd109183763c533ed15f716a300d81afaf0c10b289fbbf +size 582794 diff --git a/TGC.MonoGame.TP/Content/Textures/casaAbandonada/windows_0279_01_preview.jpg b/TGC.MonoGame.TP/Content/Textures/casaAbandonada/windows_0279_01_preview.jpg new file mode 100644 index 000000000..0af68c1f0 --- /dev/null +++ b/TGC.MonoGame.TP/Content/Textures/casaAbandonada/windows_0279_01_preview.jpg @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:099e4c0af76f79ce45d5b987e62f8fa7959a57b62f6763269e699d6d9c390c69 +size 65053 diff --git a/TGC.MonoGame.TP/Content/Textures/heighmap/Diffuse.jpg b/TGC.MonoGame.TP/Content/Textures/heighmap/Diffuse.jpg new file mode 100644 index 000000000..5682ee41d --- /dev/null +++ b/TGC.MonoGame.TP/Content/Textures/heighmap/Diffuse.jpg @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:38d46909d7a91d2903c2fff925a40dd719b1e45519a7a7e566d151323190092a +size 690916 diff --git a/TGC.MonoGame.TP/Content/Textures/heighmap/Displacement.jpg b/TGC.MonoGame.TP/Content/Textures/heighmap/Displacement.jpg new file mode 100644 index 000000000..0086a2895 --- /dev/null +++ b/TGC.MonoGame.TP/Content/Textures/heighmap/Displacement.jpg @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:08be7483dec4adb43fcf449a7bf5f7889f0a6874153955ce482d250af49dd54a +size 24446 diff --git a/TGC.MonoGame.TP/Content/Textures/heighmap/Normal Map.jpg b/TGC.MonoGame.TP/Content/Textures/heighmap/Normal Map.jpg new file mode 100644 index 000000000..6a812e225 --- /dev/null +++ b/TGC.MonoGame.TP/Content/Textures/heighmap/Normal Map.jpg @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:1fa704f5bbc5fc693318200425bcfbb707304c27f0b195df0a998413f301e00a +size 822102 diff --git a/TGC.MonoGame.TP/Content/Textures/heighmap/Snow.png b/TGC.MonoGame.TP/Content/Textures/heighmap/Snow.png new file mode 100644 index 000000000..25137c6d8 --- /dev/null +++ b/TGC.MonoGame.TP/Content/Textures/heighmap/Snow.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:428f4712486417f7de0d5d2bb79d6ada41be1f69c2c295b470263e0b7885847d +size 4376671 diff --git a/TGC.MonoGame.TP/Content/Textures/heighmap/Snow2.jpg b/TGC.MonoGame.TP/Content/Textures/heighmap/Snow2.jpg new file mode 100644 index 000000000..f158e4484 --- /dev/null +++ b/TGC.MonoGame.TP/Content/Textures/heighmap/Snow2.jpg @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:16c3b82cbacf02ad37ae1c00a9da81f4740b0200fead2c4e66c016ceadba7be5 +size 2422985 diff --git a/TGC.MonoGame.TP/Content/Textures/heighmap/heightmap.jpg b/TGC.MonoGame.TP/Content/Textures/heighmap/heightmap.jpg new file mode 100644 index 000000000..a54fdefd4 --- /dev/null +++ b/TGC.MonoGame.TP/Content/Textures/heighmap/heightmap.jpg @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:db44da81f0049fab011a5919294b8ccc0a212d62cf2080ddbc23ebf13d20ebb1 +size 28379 diff --git a/TGC.MonoGame.TP/Content/Textures/heighmap/roughness.jpg b/TGC.MonoGame.TP/Content/Textures/heighmap/roughness.jpg new file mode 100644 index 000000000..4c4f146c5 --- /dev/null +++ b/TGC.MonoGame.TP/Content/Textures/heighmap/roughness.jpg @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:fc5e7eafed0481683ae474ee1800b1f34a11bcda78d37db3a29b03b507f92a0c +size 208790 diff --git a/TGC.MonoGame.TP/Content/Textures/mouseTank.png b/TGC.MonoGame.TP/Content/Textures/mouseTank.png new file mode 100644 index 000000000..0fb2e9213 --- /dev/null +++ b/TGC.MonoGame.TP/Content/Textures/mouseTank.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:98c52ae38284ec28809dc5b4cfd45145d142c91405071d63bdfc922f843ef47f +size 1066 diff --git a/TGC.MonoGame.TP/Content/Textures/proyectilMouse.png b/TGC.MonoGame.TP/Content/Textures/proyectilMouse.png new file mode 100644 index 000000000..ace367b03 --- /dev/null +++ b/TGC.MonoGame.TP/Content/Textures/proyectilMouse.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:81e1254e20b14d19cb34f003ececd224eb8a5fd3d3065702ce47f2b7492b6150 +size 835 diff --git a/TGC.MonoGame.TP/Content/Textures/punto-de-mira.png b/TGC.MonoGame.TP/Content/Textures/punto-de-mira.png new file mode 100644 index 000000000..0a8611279 --- /dev/null +++ b/TGC.MonoGame.TP/Content/Textures/punto-de-mira.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:b18ab1db54a835b17651256018515957018adacfa53226da45d217d2bfc47df0 +size 4338 diff --git a/TGC.MonoGame.TP/Content/Textures/skyboxes/empty-space/empty-space.dds b/TGC.MonoGame.TP/Content/Textures/skyboxes/empty-space/empty-space.dds new file mode 100644 index 000000000..79fae0998 --- /dev/null +++ b/TGC.MonoGame.TP/Content/Textures/skyboxes/empty-space/empty-space.dds @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:2052983e0a47441c30d2df775a5534ac3b80f3d2c79cdbfe53513024f76b455b +size 6291584 diff --git a/TGC.MonoGame.TP/Content/Textures/skyboxes/islands/islands.dds b/TGC.MonoGame.TP/Content/Textures/skyboxes/islands/islands.dds new file mode 100644 index 000000000..7d0b5b14a --- /dev/null +++ b/TGC.MonoGame.TP/Content/Textures/skyboxes/islands/islands.dds @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:cda4801d277ef878396a90af657e0f3adb4c3ae11915f79364473253109a3fce +size 6291584 diff --git a/TGC.MonoGame.TP/Content/Textures/skyboxes/mountain_skybox_hd.dds b/TGC.MonoGame.TP/Content/Textures/skyboxes/mountain_skybox_hd.dds new file mode 100644 index 000000000..fca0c0076 --- /dev/null +++ b/TGC.MonoGame.TP/Content/Textures/skyboxes/mountain_skybox_hd.dds @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:21f3460327402fa51e968ace7e84db8ee03bffc6e1f8f1f34ed7264f8cfb2d3c +size 100663424 diff --git a/TGC.MonoGame.TP/Content/Textures/skyboxes/skybox/skybox.dds b/TGC.MonoGame.TP/Content/Textures/skyboxes/skybox/skybox.dds new file mode 100644 index 000000000..6ea3d4ae5 --- /dev/null +++ b/TGC.MonoGame.TP/Content/Textures/skyboxes/skybox/skybox.dds @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:065b6dd047bd2b3e5f729ad3b09c4e9698ffce3cac7c3baf5ffee28206884963 +size 6291584 diff --git a/TGC.MonoGame.TP/Content/Textures/skyboxes/sun-in-space/sun-in-space.dds b/TGC.MonoGame.TP/Content/Textures/skyboxes/sun-in-space/sun-in-space.dds new file mode 100644 index 000000000..bef424ecc --- /dev/null +++ b/TGC.MonoGame.TP/Content/Textures/skyboxes/sun-in-space/sun-in-space.dds @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:c9d9620d752f45f70f42e31dac907437b113e854e9ddc4e6f53bd2c1e5674b1a +size 6291584 diff --git a/TGC.MonoGame.TP/Content/Textures/skyboxes/sunset/sunset.dds b/TGC.MonoGame.TP/Content/Textures/skyboxes/sunset/sunset.dds new file mode 100644 index 000000000..a299a0ddf --- /dev/null +++ b/TGC.MonoGame.TP/Content/Textures/skyboxes/sunset/sunset.dds @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:6c9ca721ffdd9102726f2f2c93cad93f4907615c602fa6db1a035023570c1a35 +size 6291584 diff --git a/TGC.MonoGame.TP/GameObjects/FrameCounter.cs b/TGC.MonoGame.TP/GameObjects/FrameCounter.cs new file mode 100644 index 000000000..463939f35 --- /dev/null +++ b/TGC.MonoGame.TP/GameObjects/FrameCounter.cs @@ -0,0 +1,42 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace ThunderingTanks.Objects +{ + + public class FrameCounter + { + public long TotalFrames { get; private set; } + public float TotalSeconds { get; private set; } + public float AverageFramesPerSecond { get; private set; } + public float CurrentFramesPerSecond { get; private set; } + + public const int MaximumSamples = 100; + + private Queue _sampleBuffer = new(); + + public void Update(float deltaTime) + { + CurrentFramesPerSecond = 1.0f / deltaTime; + + _sampleBuffer.Enqueue(CurrentFramesPerSecond); + + if (_sampleBuffer.Count > MaximumSamples) + { + _sampleBuffer.Dequeue(); + AverageFramesPerSecond = _sampleBuffer.Average(i => i); + } + else + { + AverageFramesPerSecond = CurrentFramesPerSecond; + } + + TotalFrames++; + TotalSeconds += deltaTime; + } + } + +} diff --git a/TGC.MonoGame.TP/GameObjects/GameObject.cs b/TGC.MonoGame.TP/GameObjects/GameObject.cs new file mode 100644 index 000000000..4554628d0 --- /dev/null +++ b/TGC.MonoGame.TP/GameObjects/GameObject.cs @@ -0,0 +1,76 @@ +using Microsoft.Xna.Framework; +using Microsoft.Xna.Framework.Content; +using Microsoft.Xna.Framework.Graphics; +using ThunderingTanks.Cameras; +using ThunderingTanks.Collisions; +using ThunderingTanks.Geometries; +using ThunderingTanks.Gizmos; + +namespace ThunderingTanks.Objects +{ + public class GameObject + { + public const string ContentFolder3D = "Models/"; + public const string ContentFolderEffects = "Effects/"; + public const string ContentFolderTextures = "Textures/"; + public const string ContentFolderMusic = "Music/"; + + public Model Model { get; set; } + public Texture2D Texture { get; set; } + + public Effect Effect { get; set; } + + public Matrix WorldMatrix { get; set; } + + public Vector3 Position { get; set; } + public Vector3 LastPosition { get; set; } + + public BoundingBox BoundingBox { get; set; } + public Vector3 MaxBox; + public Vector3 MinBox; + + public GameObject() + { + WorldMatrix = Matrix.Identity; + } + + public virtual void Initialize() { } + + public virtual void Update(GameTime gameTime) { } + + public virtual void LoadContent(ContentManager Content, Effect effect) + { + Effect = effect; + } + + public virtual void Draw(Matrix view, Matrix projection) + { + foreach (var mesh in Model.Meshes) + { + + foreach (ModelMeshPart part in mesh.MeshParts) + { + part.Effect = Effect; + } + + foreach (Effect effect in mesh.Effects) + { + effect.Parameters["View"].SetValue(view); + effect.Parameters["Projection"].SetValue(projection); + } + + Effect.Parameters["ModelTexture"].SetValue(Texture); + Effect.Parameters["World"].SetValue(mesh.ParentBone.Transform * WorldMatrix); + + mesh.Draw(); + + } + } + + public void SpawnPosition(Vector3 position) + { + WorldMatrix = Matrix.CreateTranslation(position); + Position = position; + } + } +} diff --git a/TGC.MonoGame.TP/GameObjects/HUD.cs b/TGC.MonoGame.TP/GameObjects/HUD.cs new file mode 100644 index 000000000..7d798053c --- /dev/null +++ b/TGC.MonoGame.TP/GameObjects/HUD.cs @@ -0,0 +1,202 @@ +using Microsoft.Xna.Framework; +using Microsoft.Xna.Framework.Content; +using Microsoft.Xna.Framework.Graphics; +using System; +using ThunderingTanks.Objects.Tanks; + +namespace ThunderingTanks.Objects +{ + public class HUD + { + + public const string ContentFolderModels = "Models/"; + public const string ContentFolderTextures = "Textures/"; + public const string ContentFolderEffects = "Effects/"; + public const string ContentFolderFonts = "Fonts/"; + + private float ScreenWidth { get; set; } + private float ScreenHeight { get; set; } + + private Rectangle lifeBar; + + private Texture2D lifeBar11; + private Texture2D lifeBar10; + private Texture2D lifeBar9; + private Texture2D lifeBar8; + private Texture2D lifeBar7; + private Texture2D lifeBar6; + private Texture2D lifeBar5; + private Texture2D lifeBar4; + private Texture2D lifeBar3; + private Texture2D lifeBar2; + private Texture2D lifeBar1; + + private Texture2D lifeBarTexture; + + private Texture2D CrossHairTexture; + public bool DrawDebug { get; set; } = false; + + public float Convergence { get; set; } = 1000f; + private Vector2 CrossHairPosition; + + private SpriteFont FontArial; + + private SpriteFont WarIsOver; + + private float puntos; + + public int _maxLifeBarWidth; + public bool siguienteOleada; + + #region Debug + public Vector3 TankPosition { get; set; } + public int BulletCount { get; set; } + public bool TankIsColliding { get; set; } + public float FPS { get; set; } + public float TimeSinceLastShot { get; set; } + public Vector3 RayPosition { get; set; } + public Vector3 RayDirection { get; set; } + + public float elapsedTime { get; set; } + public float Oleada { get; set; } + #endregion + + public HUD(float screenWidth, float screenHeight) + { + ScreenWidth = screenWidth; + ScreenHeight = screenHeight; + + float barWidth = screenWidth / 10; + float barHeight = screenHeight / 20; + float barY = 10; + float barX = screenWidth - 2 * barWidth + 30; + + lifeBar = new Rectangle((int)barX, (int)barY, (int)barWidth, (int)barHeight); + } + + public void LoadContent(ContentManager Content) + { + CrossHairTexture = Content.Load(ContentFolderTextures + "/punto-de-mira"); + FontArial = Content.Load(ContentFolderFonts + "arial"); + + lifeBar1 = Content.Load(ContentFolderTextures + "HUD/lifebar/1"); + lifeBar2 = Content.Load(ContentFolderTextures + "HUD/lifebar/2"); + lifeBar3 = Content.Load(ContentFolderTextures + "HUD/lifebar/3"); + lifeBar4 = Content.Load(ContentFolderTextures + "HUD/lifebar/4"); + lifeBar5 = Content.Load(ContentFolderTextures + "HUD/lifebar/5"); + lifeBar6 = Content.Load(ContentFolderTextures + "HUD/lifebar/6"); + lifeBar7 = Content.Load(ContentFolderTextures + "HUD/lifebar/7"); + lifeBar8 = Content.Load(ContentFolderTextures + "HUD/lifebar/8"); + lifeBar9 = Content.Load(ContentFolderTextures + "HUD/lifebar/9"); + lifeBar10 = Content.Load(ContentFolderTextures + "HUD/lifebar/10"); + lifeBar11 = Content.Load(ContentFolderTextures + "HUD/lifebar/11"); + + WarIsOver = Content.Load(ContentFolderFonts + "warisover/WarIsOver"); + + lifeBarTexture = lifeBar1; + + _maxLifeBarWidth = lifeBar.Width; + siguienteOleada = false; + } + + public void Update(Tank Panzer, ref Viewport viewport, float TanksEliminados) + { + CrossHairPosition = new Vector2(ScreenWidth / 2 - 25, (float)((Math.Tan(Panzer.GunElevation) * Convergence) + (ScreenHeight / 2) - 10)); + lifeBarTexture = lifeBar1; + + #region LifeBar + + if (Panzer.CurrentLife == 50) + { + lifeBarTexture = lifeBar1; + } + else if (Panzer.CurrentLife == 45) + { + lifeBarTexture = lifeBar2; + } + else if (Panzer.CurrentLife == 40) + { + lifeBarTexture = lifeBar3; + } + else if (Panzer.CurrentLife == 35) + { + lifeBarTexture = lifeBar4; + } + else if (Panzer.CurrentLife == 30) + { + lifeBarTexture = lifeBar5; + } + else if (Panzer.CurrentLife == 25) + { + lifeBarTexture = lifeBar6; + } + else if (Panzer.CurrentLife == 20) + { + lifeBarTexture = lifeBar7; + } + else if (Panzer.CurrentLife == 15) + { + lifeBarTexture = lifeBar8; + } + else if (Panzer.CurrentLife == 10) + { + lifeBarTexture = lifeBar9; + } + else if(Panzer.CurrentLife == 5) + { + lifeBarTexture = lifeBar10; + } + else + { + lifeBarTexture = lifeBar11; + } + #endregion + + puntos = TanksEliminados; + } + + public void Draw(SpriteBatch spriteBatch) + { + spriteBatch.Draw( + CrossHairTexture, + CrossHairPosition, + null, Color.Black, 0f, Vector2.Zero, 0.1f, SpriteEffects.None, 0.8f + ); + + spriteBatch.Draw( + lifeBarTexture, + lifeBar, + Color.Yellow + ); + + spriteBatch.DrawString(WarIsOver, "OLEADA: " + Oleada, new Vector2(ScreenWidth - 250, ScreenHeight - 150), Color.Blue); + + spriteBatch.DrawString(WarIsOver, "PUNTOS: " + puntos, new Vector2(ScreenWidth - 250, ScreenHeight - 100), Color.Blue); + + spriteBatch.DrawString(WarIsOver, "TIEMPO: " + (int)elapsedTime + " SEGS", new Vector2(ScreenWidth - 250, ScreenHeight - 50), Color.Blue); + + if(siguienteOleada) + { + spriteBatch.DrawString(WarIsOver, "OLEADA COMPLETADA", new Vector2(ScreenWidth - 1005, ScreenHeight - 525), Color.GreenYellow); + spriteBatch.DrawString(WarIsOver, "SIGUIENTE OLEADA: " + Oleada, new Vector2(ScreenWidth - 1000, ScreenHeight - 500), Color.GreenYellow); + } + + if(DrawDebug) + { + #region Debug + + spriteBatch.DrawString(FontArial, "Debug", new Vector2(20, 20), Color.Red); + spriteBatch.DrawString(FontArial, "Cantidad De Balas: " + BulletCount.ToString(), new Vector2(20, 40), Color.Red); + spriteBatch.DrawString(FontArial, "Posicion Del Tanque: " + "X:" + TankPosition.X.ToString() + "Y:" + TankPosition.Y.ToString() + " Z:" + TankPosition.Z.ToString(), new Vector2(20, 60), Color.Red); + spriteBatch.DrawString(FontArial, (TankIsColliding) ? "Coliciona" : "No Coliciona", new Vector2(20, 80), Color.Red); + spriteBatch.DrawString(FontArial, "Reloading Time: " + TimeSinceLastShot, new Vector2(20, 100), Color.Red); + spriteBatch.DrawString(FontArial, "Distancia De Apuntado " + Convergence, new Vector2(20, 120), Color.Red); + spriteBatch.DrawString(FontArial, "Posicion Del Rayo" + " " + RayPosition.X + " " + RayPosition.Y + " " + RayPosition.Z, new Vector2(20, 140), Color.Red); + spriteBatch.DrawString(FontArial, "Direccion Del Rayo" + " " + RayDirection.X + " " + RayDirection.Y + " " + RayDirection.Z, new Vector2(20, 160), Color.Red); + spriteBatch.DrawString(FontArial, "FPS " + Math.Round(FPS), new Vector2(20, 180), Color.Red); + + #endregion + } + } + } +} diff --git a/TGC.MonoGame.TP/GameObjects/MapScene.cs b/TGC.MonoGame.TP/GameObjects/MapScene.cs new file mode 100644 index 000000000..4692dbddc --- /dev/null +++ b/TGC.MonoGame.TP/GameObjects/MapScene.cs @@ -0,0 +1,64 @@ + +using Microsoft.Xna.Framework; +using Microsoft.Xna.Framework.Content; +using Microsoft.Xna.Framework.Graphics; +using System; +using System.Collections.Generic; +using System.Drawing.Imaging; +using System.Linq; +using System.Reflection.Metadata.Ecma335; + + +namespace ThunderingTanks.Objects +{ + + /// + /// Conteins the map for the game + /// + class MapScene + { + public const string ContentFolder3D = "Models/"; + public const string ContentFolderEffects = "Effects/"; + public const string ContentFolderTextures = "Textures/"; + + private Texture2D DiffuseTexture { get; set; } + private Texture2D DiffuseTexture2 { get; set; } + private Texture2D DisplacementTexture { get; set; } + private Texture2D ColorMap { get; set; } + + private Effect TerrainEffect { get; set; } + + public SimpleTerrain terrain; + + /// + /// Creates the Map For The Game + /// + /// The Content Manager to load resources + public MapScene(ContentManager content, GraphicsDevice graphicsDevice) + { + TerrainEffect = content.Load(ContentFolderEffects + "BasicShader"); + + DiffuseTexture = content.Load(ContentFolderTextures + "/heighmap/Snow"); + DiffuseTexture2 = content.Load(ContentFolderTextures + "/heighmap/Snow2"); + DisplacementTexture = content.Load(ContentFolderTextures + "/heighmap/Displacement"); + ColorMap = content.Load(ContentFolderTextures + "/heighmap/heightmap"); + + terrain = new SimpleTerrain(graphicsDevice, DisplacementTexture, ColorMap, DiffuseTexture, DiffuseTexture2, TerrainEffect); + + } + + public void Draw(GameTime gameTime, Matrix view, Matrix projection, GraphicsDevice graphicsDevice) + { + graphicsDevice.DepthStencilState = DepthStencilState.Default; + var oldRasterizeState = graphicsDevice.RasterizerState; + graphicsDevice.RasterizerState = RasterizerState.CullNone; + + + terrain.Draw(Matrix.Identity * Matrix.CreateTranslation(new Vector3(0f, -450f, 0f)), view, projection); + + + graphicsDevice.RasterizerState = oldRasterizeState; + + } + } +} diff --git a/TGC.MonoGame.TP/GameObjects/Menu.cs b/TGC.MonoGame.TP/GameObjects/Menu.cs new file mode 100644 index 000000000..183dfb272 --- /dev/null +++ b/TGC.MonoGame.TP/GameObjects/Menu.cs @@ -0,0 +1,198 @@ +using System; +using Microsoft.Xna.Framework; +using Microsoft.Xna.Framework.Content; +using Microsoft.Xna.Framework.Graphics; +using Microsoft.Xna.Framework.Input; +using Microsoft.Xna.Framework.Media; + + + +namespace ThunderingTanks.Objects +{ + public class Menu + { + public const string ContentFolderMusic = "Music/"; + public const string ContentFolderModels = "Models/"; + public const string ContentFolderTextures = "Textures/"; + public const string ContentFolderEffects = "Effects/"; + public const string ContentFolderFonts = "Fonts/"; + + private float ScreenWidth { get; set; } + private float ScreenHeight { get; set; } + + public float MasterSound { get; set; } + private Song backgroundSound { get; set; } + + private SpriteFont _font; + private SpriteFont WarIsOver; + + private Texture2D _cursorTexture; + + private bool _playing = true; + + #region BOTONS + + private Rectangle _playButton; + private Rectangle _exitButton; + private Rectangle _soundOnButton; + private Rectangle _soundOffButton; + private Texture2D RectangleButtonHover { get; set; } + private Texture2D RectangleButton { get; set; } + private Texture2D PlayButton { get; set; } + private Texture2D PlayButtonHover { get; set; } + private Texture2D SoundOnButton { get; set; } + private Texture2D SoundOnButtonHover { get; set; } + private Texture2D SoundOffButton { get; set; } + private Texture2D SoundOffButtonHover { get; set; } + private Texture2D RectangleButtonNormal { get; set; } + private Texture2D PlayButtonNormal { get; set; } + private Texture2D SoundOnButtonNormal { get; set; } + private Texture2D SoundOffButtonNormal { get; set; } + + #endregion + + private bool SoundIsOn = true; + private bool ResetMouse = true; + + public Menu(ContentManager contentManager) + { + ScreenWidth = GraphicsAdapter.DefaultAdapter.CurrentDisplayMode.Width; + ScreenHeight = GraphicsAdapter.DefaultAdapter.CurrentDisplayMode.Height; + + int buttonWidth = 400; + int buttonHeight = 200; + int buttonSpacing = 20; + + int buttonY = (int) (ScreenHeight - 2 * buttonHeight - buttonSpacing) / 2; + int buttonX = (int) ScreenWidth - buttonWidth - 300; + + _playButton = new Rectangle(buttonX, buttonY, buttonWidth, buttonHeight); + _exitButton = new Rectangle(buttonX, buttonY + buttonHeight + buttonSpacing, buttonWidth, buttonHeight); + + _soundOnButton = new Rectangle(50, (int)(ScreenHeight - 150), 100, 100); + _soundOffButton = new Rectangle(50, (int)(ScreenHeight - 150), 100, 100); + } + + public void LoadContent(ContentManager Content) + { + + backgroundSound = Content.Load(ContentFolderMusic + "TankGameBackgroundSound"); + _cursorTexture = Content.Load(ContentFolderTextures + "proyectilMouse"); + _font = Content.Load(ContentFolderFonts + "arial"); + WarIsOver = Content.Load(ContentFolderFonts + "warisover/WarIsOver"); + + RectangleButtonNormal = Content.Load(ContentFolderTextures + "Menu/Default@4x"); + PlayButtonNormal = Content.Load(ContentFolderTextures + "Menu/PlayButton"); + SoundOnButtonNormal = Content.Load(ContentFolderTextures + "Menu/SoundOn"); + SoundOffButtonNormal = Content.Load(ContentFolderTextures + "Menu/SoundOff"); + + RectangleButtonHover = Content.Load(ContentFolderTextures + "Menu/RectangleButtonHover"); + PlayButtonHover = Content.Load(ContentFolderTextures + "Menu/PlayButtonHover"); + SoundOnButtonHover = Content.Load(ContentFolderTextures + "Menu/SoundOnHover"); + SoundOffButtonHover = Content.Load(ContentFolderTextures + "Menu/SoundOffHover"); + + } + + public void Update(ref bool juegoIniciado, GameTime gameTime) + { + var mouseState = Mouse.GetState(); + var mousePosition = new Point(mouseState.X, mouseState.Y); + + if (mouseState.LeftButton == ButtonState.Released) + ResetMouse = true; + + if (mouseState.LeftButton == ButtonState.Pressed) + { + if (_playButton.Contains(mousePosition)) + { + juegoIniciado = true; + MediaPlayer.Stop(); + } + else if (_exitButton.Contains(mousePosition)) + { + Environment.Exit(0); + } + + if (SoundIsOn && _soundOffButton.Contains(mousePosition) && ResetMouse) + { + if (MediaPlayer.State == MediaState.Playing) + MediaPlayer.Pause(); + + SoundIsOn = false; + ResetMouse = false; + } + else if (!SoundIsOn && _soundOnButton.Contains(mousePosition) && ResetMouse) + { + if (MediaPlayer.State == MediaState.Paused) + MediaPlayer.Resume(); + + SoundIsOn = true; + ResetMouse = false; + } + } + + if (_playButton.Contains(mousePosition)) + { + PlayButton = PlayButtonHover; + } + else + { + PlayButton = PlayButtonNormal; + } + + if (_exitButton.Contains(mousePosition)) + { + RectangleButton = RectangleButtonHover; + } + else + { + RectangleButton = RectangleButtonNormal; + } + + if (_soundOnButton.Contains(mousePosition)) + { + SoundOnButton = SoundOnButtonHover; + } + else + { + SoundOnButton = SoundOnButtonNormal; + } + + if (_soundOffButton.Contains(mousePosition)) + { + SoundOffButton = SoundOffButtonHover; + } + else + { + SoundOffButton = SoundOffButtonNormal; + } + + if (_playing) + { + MediaPlayer.Play(backgroundSound); + _playing = false; + } + + } + + public void Draw(SpriteBatch spriteBatch) + { + + var mouseState = Mouse.GetState(); + + Vector2 exitTextPosition = new(_exitButton.X + (_exitButton.Width - (_font.MeasureString("Exit").X + 70)) / 2, _exitButton.Y + (_exitButton.Height - (_font.MeasureString("Exit").Y + 70)) / 2); + + if (SoundIsOn) + spriteBatch.Draw(SoundOnButton, _soundOnButton, Color.Gray); + else + spriteBatch.Draw(SoundOffButton, _soundOffButton, Color.Gray); + + spriteBatch.Draw(PlayButton, _playButton, Color.Gray); + spriteBatch.Draw(RectangleButton, _exitButton, Color.Gray); + spriteBatch.Draw(_cursorTexture, new Vector2(mouseState.X, mouseState.Y), Color.White); + spriteBatch.DrawString(WarIsOver, "THUNDERING TANKS", new Vector2(450, 200), Color.SandyBrown); + spriteBatch.DrawString(WarIsOver, "VOLUMEN = " + MasterSound.ToString("P"), new Vector2(50, ScreenHeight - 200), Color.SaddleBrown); + spriteBatch.DrawString(WarIsOver, "EXIT", exitTextPosition, Color.White, 0f, Vector2.Zero, 3f, SpriteEffects.None, 0f); + } + } +} diff --git a/TGC.MonoGame.TP/GameObjects/Particles/Particle.cs b/TGC.MonoGame.TP/GameObjects/Particles/Particle.cs new file mode 100644 index 000000000..61ecd75ec --- /dev/null +++ b/TGC.MonoGame.TP/GameObjects/Particles/Particle.cs @@ -0,0 +1,37 @@ +using Microsoft.Xna.Framework; +using Microsoft.Xna.Framework.Graphics; +using System; +using System.Collections.Generic; +namespace ThunderingTanks.Objects; +public class Particle +{ + public Vector2 Position; + public Vector2 Velocity; + public float Lifetime; + public float Size; + public float InitialLifetime; // Para guardar el valor inicial de Lifetime + public Color Color; + + public Particle(Vector2 position, Vector2 velocity, float lifetime, float size, Color color) + { + Position = position; + Velocity = velocity; + Lifetime = lifetime; + InitialLifetime = lifetime; // Guardamos el valor inicial + Size = size; + Color = color; + } + + public void Update(float deltaTime) + { + Position += Velocity * deltaTime; + Lifetime -= deltaTime; + float alpha = Lifetime / InitialLifetime; // Calcula el alpha basado en la vida restante + Color = new Color(Color.R, Color.G, Color.B, alpha); + } + + public void Draw(SpriteBatch spriteBatch, Texture2D pixel) + { + spriteBatch.Draw(pixel, new Rectangle((int)Position.X, (int)Position.Y, (int)Size, (int)Size), Color); + } +} diff --git a/TGC.MonoGame.TP/GameObjects/Particles/ParticleSystem.cs b/TGC.MonoGame.TP/GameObjects/Particles/ParticleSystem.cs new file mode 100644 index 000000000..61cf8f8a5 --- /dev/null +++ b/TGC.MonoGame.TP/GameObjects/Particles/ParticleSystem.cs @@ -0,0 +1,49 @@ +using Microsoft.Xna.Framework; +using Microsoft.Xna.Framework.Graphics; +using System; +using System.Collections.Generic; +namespace ThunderingTanks.Objects; +public class ParticleSystem +{ + private List particles; + private Random random; + private Texture2D pixel; + + public ParticleSystem(GraphicsDevice graphicsDevice) + { + particles = new List(); + random = new Random(); + pixel = new Texture2D(graphicsDevice, 1, 1); + pixel.SetData(new[] { Color.Gray }); + } + + public void AddParticle(Vector2 position) + { + float lifetime = (float)random.NextDouble() * 1f + 9f; + float size = (float)random.NextDouble() * 7f + 1f; + Vector2 velocity = new Vector2((float)(random.NextDouble() * 2 - 1), (float)(-random.NextDouble() * 2 - 15)); // Ajuste de desplazamiento hacia arriba + Color color = Color.Gray * 10f; + particles.Add(new Particle(position, velocity, lifetime, size, color)); + + } + + public void Update(float deltaTime) + { + for (int i = particles.Count - 1; i >= 0; i--) + { + particles[i].Update(deltaTime); + if (particles[i].Lifetime <= 0) + { + particles.RemoveAt(i); + } + } + } + + public void Draw(SpriteBatch spriteBatch) + { + foreach (var particle in particles) + { + particle.Draw(spriteBatch, pixel); + } + } +} diff --git a/TGC.MonoGame.TP/GameObjects/Props/AntiTanque.cs b/TGC.MonoGame.TP/GameObjects/Props/AntiTanque.cs new file mode 100644 index 000000000..3e8f53e62 --- /dev/null +++ b/TGC.MonoGame.TP/GameObjects/Props/AntiTanque.cs @@ -0,0 +1,111 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using Microsoft.Xna.Framework; +using Microsoft.Xna.Framework.Content; +using Microsoft.Xna.Framework.Graphics; + +namespace ThunderingTanks.Objects.Props +{ + public class AntiTanque + { + public const string ContentFolder3D = "Models/"; + public const string ContentFolderEffects = "Effects/"; + public Model AntitanqueModel { get; set; } + + private Texture2D TexturaAntitanque { get; set; } + public Matrix[] AntitanqueWorlds { get; set; } + public Effect Effect { get; set; } + public BoundingBox AntiTanqueBox { get; set; } + + public Vector3 originalPosition; + + public AntiTanque() + { + AntitanqueWorlds = new Matrix[] { }; + } + + public void AgregarAntitanque(Vector3 Position) + { + Matrix posicionAntitanque = Matrix.CreateTranslation(Position) * Matrix.Identity; + var nuevoAntitanque = new Matrix[]{ + posicionAntitanque * Matrix.CreateScale(500), + }; + AntitanqueWorlds = AntitanqueWorlds.Concat(nuevoAntitanque).ToArray(); + originalPosition = Position; + } + + public void LoadContent(ContentManager Content, Effect effect) + { + AntitanqueModel = Content.Load(ContentFolder3D + "assets militares/rsg_military_antitank_hedgehog_01"); + + TexturaAntitanque = Content.Load(ContentFolder3D + "assets militares/Textures/UE/T_rsg_military_sandbox_01_BC"); + Effect = effect; + foreach (var mesh in AntitanqueModel.Meshes) + { + foreach (var meshPart in mesh.MeshParts) + { + meshPart.Effect = Effect; + } + } + AntiTanqueBox = CreateBoundingBox(AntitanqueModel, Matrix.CreateScale(2.5f), originalPosition); + } + + public void Draw(GameTime gameTime, Matrix view, Matrix projection, SimpleTerrain terrain) + { + // Update the tree's position based on the terrain height + float terrainHeight = terrain.Height(originalPosition.X, originalPosition.Z); + Vector3 adjustedPosition = new Vector3(originalPosition.X, terrainHeight - 1100, originalPosition.Z); + + Effect.Parameters["View"].SetValue(view); + Effect.Parameters["Projection"].SetValue(projection); + Effect.Parameters["ModelTexture"].SetValue(TexturaAntitanque); + + //Effect.Parameters["DiffuseColor"].SetValue(Color.Black.ToVector3()); + foreach (var mesh in AntitanqueModel.Meshes) + { + + for (int i = 0; i < AntitanqueWorlds.Length; i++) + { + Matrix _antitanqueWorld = AntitanqueWorlds[i] * Matrix.CreateTranslation(adjustedPosition); + Effect.Parameters["World"].SetValue(mesh.ParentBone.Transform * _antitanqueWorld); + mesh.Draw(); + } + + } + } + private BoundingBox CreateBoundingBox(Model model, Matrix escala, Vector3 position) + { + var minPoint = Vector3.One * float.MaxValue; + var maxPoint = Vector3.One * float.MinValue; + + var transforms = new Matrix[model.Bones.Count]; + model.CopyAbsoluteBoneTransformsTo(transforms); + + foreach (var mesh in model.Meshes) + { + var meshParts = mesh.MeshParts; + foreach (var meshPart in meshParts) + { + var vertexBuffer = meshPart.VertexBuffer; + var declaration = vertexBuffer.VertexDeclaration; + var vertexSize = declaration.VertexStride / sizeof(float); + + var rawVertexBuffer = new float[vertexBuffer.VertexCount * vertexSize]; + vertexBuffer.GetData(rawVertexBuffer); + + for (var vertexIndex = 0; vertexIndex < rawVertexBuffer.Length; vertexIndex += vertexSize) + { + var transform = transforms[mesh.ParentBone.Index] * escala; + var vertex = new Vector3(rawVertexBuffer[vertexIndex], rawVertexBuffer[vertexIndex + 1], rawVertexBuffer[vertexIndex + 2]); + vertex = Vector3.Transform(vertex, transform); + minPoint = Vector3.Min(minPoint, vertex); + maxPoint = Vector3.Max(maxPoint, vertex); + } + } + } + + return new BoundingBox(minPoint + position, maxPoint + position); + } + } +} \ No newline at end of file diff --git a/TGC.MonoGame.TP/GameObjects/Props/DestroyedHouse.cs b/TGC.MonoGame.TP/GameObjects/Props/DestroyedHouse.cs new file mode 100644 index 000000000..792969729 --- /dev/null +++ b/TGC.MonoGame.TP/GameObjects/Props/DestroyedHouse.cs @@ -0,0 +1,41 @@ +using Microsoft.Xna.Framework; +using Microsoft.Xna.Framework.Content; +using Microsoft.Xna.Framework.Graphics; + +namespace ThunderingTanks.Objects.Props +{ + public class DestroyedHouse : GameObject + { + + public Matrix[] CasaWorlds { get; set; } + + public DestroyedHouse() + { + CasaWorlds = System.Array.Empty(); + + MaxBox = new Vector3(100f, 1500f, 2000f); + MinBox = new Vector3(-1900f, 700f, 300f); + } + + public override void LoadContent(ContentManager Content, Effect effect) + { + Model = Content.Load(ContentFolder3D + "casa/house"); + + Texture = Content.Load(ContentFolderTextures + "casaAbandonada/Medieval_Brick_Texture_by_goodtextures"); + + Effect = effect; + + foreach (var mesh in Model.Meshes) + { + foreach (var meshPart in mesh.MeshParts) + { + meshPart.Effect = Effect; + } + } + + WorldMatrix = Matrix.CreateScale(500f) * Matrix.CreateTranslation(Position); + + BoundingBox = new BoundingBox(Position + MinBox, Position + MaxBox); + } + } +} \ No newline at end of file diff --git a/TGC.MonoGame.TP/GameObjects/Props/GermanSoldier.cs b/TGC.MonoGame.TP/GameObjects/Props/GermanSoldier.cs new file mode 100644 index 000000000..aacdfd948 --- /dev/null +++ b/TGC.MonoGame.TP/GameObjects/Props/GermanSoldier.cs @@ -0,0 +1,74 @@ +using Microsoft.Extensions.Configuration; +using Microsoft.Xna.Framework; +using Microsoft.Xna.Framework.Content; +using Microsoft.Xna.Framework.Graphics; +using System.Collections.Generic; +using ThunderingTanks.Animation.Models; +using ThunderingTanks.Animation.PipelineExtensions; +using MonoGame.Extended; +using System.DirectoryServices; + +namespace ThunderingTanks.Objects.Props +{ + internal class GermanSoldier : GameObject + { + new public AnimatedModel Model { get; set; } + public AnimatedModel Animation { get; set; } + private List AnimationNames { get; set; } + private ContentManager ContentManager { get; set; } + + private IConfigurationRoot Configuration { get; set; } + + readonly string AnimationFolder = "Models/GermanModel"; + readonly string AnimatedModelFolder = ContentFolder3D + "GermanModel/GermanSoldier"; + + public override void Initialize() + { + var configurationFileName = "app-settings.json"; + Configuration = new ConfigurationBuilder().AddJsonFile(configurationFileName, true, true).Build(); + } + + public override void LoadContent(ContentManager Content, Effect effect) + { + + ContentManager = Content; + + AnimationNames = new List + { + AnimationFolder + "/GermanSoldier_1", + AnimationFolder + "/GermanSoldier_2", + }; + + var manager = CustomPipelineManager.CreateCustomPipelineManager(Configuration); + + foreach (var model in AnimationNames) + { + manager.BuildAnimationContent(model); + } + + manager.BuildAnimationContent(AnimatedModelFolder); + + Model = new AnimatedModel(AnimatedModelFolder); + Model.LoadContent(Content); + + Texture2D GermanSoldierTexture = Content.Load(ContentFolder3D + "GermanModel/Wermarcht_albedo"); + Texture = GermanSoldierTexture; + + Effect = effect; + } + + public override void Draw(Matrix view, Matrix projection) + { + Model.Draw(WorldMatrix, view, projection); + } + + public void ChangeAnimation() + { + Animation = new AnimatedModel(AnimationNames[0]); + Animation.LoadContent(ContentManager); + + var player = Model.PlayClip(Animation.Clips[0]); + player.Looping = true; + } + } +} diff --git a/TGC.MonoGame.TP/GameObjects/Props/Grass.cs b/TGC.MonoGame.TP/GameObjects/Props/Grass.cs new file mode 100644 index 000000000..9c774db9f --- /dev/null +++ b/TGC.MonoGame.TP/GameObjects/Props/Grass.cs @@ -0,0 +1,70 @@ +using Microsoft.Xna.Framework.Content; +using Microsoft.Xna.Framework.Graphics; +using Microsoft.Xna.Framework; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Reflection.Metadata; + +namespace ThunderingTanks.Objects.Props +{ + internal class Grass : GameObject + { + private Texture2D GrassApha { get; set; } + private Texture2D GrassColor { get; set; } + private Texture2D GrassNormal { get; set; } + private Texture2D GrassSmoothness { get; set; } + + private Vector3 originalPosition; + + + public override void LoadContent(ContentManager Content, Effect effect) + { + Model grassModel = Content.Load(ContentFolder3D + "grass/grasspatches"); + Texture2D grassAlpha = Content.Load(ContentFolder3D + "grass/grassAlphaMapped"); + Texture2D grassColor = Content.Load(ContentFolder3D + "grass/grasscolor"); + Texture2D grassNormal = Content.Load(ContentFolder3D + "grass/grassNormal"); + Texture2D grassSmoothness = Content.Load(ContentFolder3D + "grass/grassSmoothness"); + + Model = grassModel; + GrassApha = grassAlpha; + GrassColor = grassColor; + GrassNormal = grassNormal; + GrassSmoothness = grassSmoothness; + Effect = effect; + } + + public void Draw(List positions, Matrix view, Matrix projection, SimpleTerrain terrain) + { + + foreach (var position in positions) + { + originalPosition = position; + float terrainHeight = terrain.Height(originalPosition.X, originalPosition.Z); + Vector3 adjustedPosition = new Vector3(originalPosition.X, terrainHeight - 450, originalPosition.Z); + + foreach (var mesh in Model.Meshes) + { + + foreach (ModelMeshPart part in mesh.MeshParts) + { + part.Effect = Effect; + } + + foreach (Effect effect in mesh.Effects) + { + effect.Parameters["View"].SetValue(view); + effect.Parameters["Projection"].SetValue(projection); + } + + Effect.Parameters["ModelTexture"].SetValue(GrassApha); + Effect.Parameters["World"].SetValue(mesh.ParentBone.Transform * Matrix.CreateTranslation(adjustedPosition)); + + mesh.Draw(); + } + } + } + } +} diff --git a/TGC.MonoGame.TP/GameObjects/Props/Molino.cs b/TGC.MonoGame.TP/GameObjects/Props/Molino.cs new file mode 100644 index 000000000..a02353da9 --- /dev/null +++ b/TGC.MonoGame.TP/GameObjects/Props/Molino.cs @@ -0,0 +1,101 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using Microsoft.Xna.Framework; +using Microsoft.Xna.Framework.Content; +using Microsoft.Xna.Framework.Graphics; + +namespace ThunderingTanks.Objects.Props +{ + public class Molino + { + public const string ContentFolder3D = "Models/"; + public const string ContentFolderEffects = "Effects/"; + + public Model MolinoModel { get; set; } + public Texture2D MolinoTexture { get; set; } + public Matrix MolinoMatrix { get; set; } + public Effect MolinoEffect { get; set; } + public Vector3 Position; + public BoundingBox MolinoBox { get; set; } + + public Molino(Matrix molinoMatrix) + { + MolinoMatrix = molinoMatrix; + } + + public void LoadContent(ContentManager Content, Effect effect) + { + MolinoModel = Content.Load(ContentFolder3D + "ModelosVarios/MolinoProp/MolinoProp"); + MolinoTexture = Content.Load(ContentFolder3D + "ModelosVarios/MolinoProp/T_Windpump_D"); + MolinoEffect = effect; + + foreach (var mesh in MolinoModel.Meshes) + { + if (mesh.Name == "SM_WindPump") + { + foreach (var meshPart in mesh.MeshParts) + { + meshPart.Effect = MolinoEffect; + } + } + } + Position = Matrix.Invert(MolinoMatrix).Translation; + MolinoBox = CreateBoundingBox(MolinoModel, Matrix.CreateScale(2.5f), Position); + } + + public void Draw(GameTime gameTime, Matrix view, Matrix projection) + { + MolinoEffect.Parameters["View"].SetValue(view); + MolinoEffect.Parameters["Projection"].SetValue(projection); + MolinoEffect.Parameters["ModelTexture"].SetValue(MolinoTexture); + + Matrix _molinoMatrix = MolinoMatrix * Matrix.CreateTranslation(100, 0, 555); + + foreach (var mesh in MolinoModel.Meshes) + { + if (mesh.Name == "SM_WindPump") + { + MolinoEffect.Parameters["ModelTexture"].SetValue(MolinoTexture); + MolinoEffect.Parameters["World"].SetValue(mesh.ParentBone.Transform * _molinoMatrix); + + mesh.Draw(); + } + } + } + private BoundingBox CreateBoundingBox(Model model, Matrix escala, Vector3 position) + { + var minPoint = Vector3.One * float.MaxValue; + var maxPoint = Vector3.One * float.MinValue; + + var transforms = new Matrix[model.Bones.Count]; + model.CopyAbsoluteBoneTransformsTo(transforms); + + foreach (var mesh in model.Meshes) + { + var meshParts = mesh.MeshParts; + foreach (var meshPart in meshParts) + { + var vertexBuffer = meshPart.VertexBuffer; + var declaration = vertexBuffer.VertexDeclaration; + var vertexSize = declaration.VertexStride / sizeof(float); + + var rawVertexBuffer = new float[vertexBuffer.VertexCount * vertexSize]; + vertexBuffer.GetData(rawVertexBuffer); + + for (var vertexIndex = 0; vertexIndex < rawVertexBuffer.Length; vertexIndex += vertexSize) + { + var transform = transforms[mesh.ParentBone.Index] * escala; + var vertex = new Vector3(rawVertexBuffer[vertexIndex], rawVertexBuffer[vertexIndex + 1], rawVertexBuffer[vertexIndex + 2]); + vertex = Vector3.Transform(vertex, transform); + minPoint = Vector3.Min(minPoint, vertex); + maxPoint = Vector3.Max(maxPoint, vertex); + } + } + } + + return new BoundingBox(minPoint + position, maxPoint + position); + } + + } +} diff --git a/TGC.MonoGame.TP/GameObjects/Props/Roca.cs b/TGC.MonoGame.TP/GameObjects/Props/Roca.cs new file mode 100644 index 000000000..ae5c2f674 --- /dev/null +++ b/TGC.MonoGame.TP/GameObjects/Props/Roca.cs @@ -0,0 +1,148 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using Microsoft.Xna.Framework; +using Microsoft.Xna.Framework.Content; +using Microsoft.Xna.Framework.Graphics; +using ThunderingTanks.Collisions; + +namespace ThunderingTanks.Objects.Props +{ + public class Roca + { + public const string ContentFolder3D = "Models/"; + public const string ContentFolderEffects = "Effects/"; + public Model RocaModel { get; set; } + + private Texture2D TexturaRoca { get; set; } + public Matrix[] RocaWorlds { get; set; } + public Matrix RocaWorld { get; set; } + public Effect Effect { get; set; } + + public BoundingBox RocaBox { get; set; } + public Vector3 Position { get; set; } + + public List BoundingBoxes { get; private set; } + + public bool IsDestroyed { get; private set; } // Indica si la roca ha sido destruida + private Vector3 originalPosition; + + + public Roca() + { + RocaWorld = Matrix.Identity; + } + + public void LoadContent(ContentManager content, Effect effect,SimpleTerrain terrain) + { + RocaModel = content.Load(ContentFolder3D + "nature/rock/Rock_1"); + TexturaRoca = content.Load(ContentFolder3D + "nature/rock/Yeni klasör/Rock_1_Base_Color"); + Effect = effect; + + foreach (var mesh in RocaModel.Meshes) + { + foreach (var meshPart in mesh.MeshParts) + { + meshPart.Effect = Effect; + } + } + + Random random = new Random(); + + originalPosition = Position; + float terrainHeight = terrain.Height(originalPosition.X, originalPosition.Z); + Vector3 adjustedPosition = new Vector3(originalPosition.X, terrainHeight - 300, originalPosition.Z); + + RocaWorld = Matrix.CreateTranslation(adjustedPosition); + RocaWorld = + Matrix.CreateScale(2.5f) + * Matrix.CreateRotationY((float)random.NextDouble()) + * Matrix.CreateRotationX((float)random.NextDouble()) + * Matrix.CreateRotationZ((float)random.NextDouble()) + * Matrix.CreateTranslation(adjustedPosition); + + RocaBox = CreateBoundingBox(RocaModel, Matrix.CreateScale(2.5f), adjustedPosition); + + } + public void Draw(GameTime gameTime, Matrix view, Matrix projection) + + { + if (!IsDestroyed) + { + Effect.Parameters["Projection"]?.SetValue(projection); + Effect.Parameters["View"]?.SetValue(view); + + foreach (var mesh in RocaModel.Meshes) + { + Matrix rocaWorld = RocaWorld; + Effect.Parameters["ModelTexture"]?.SetValue(TexturaRoca); + Effect.Parameters["World"]?.SetValue(mesh.ParentBone.Transform * rocaWorld); + mesh.Draw(); + } + } + } + + public void Destroy() + { + IsDestroyed = true; + DestruirRecursos(); + DestruirBoundingBox(); + } + + public void DestruirRecursos() + { + //RocaModel?.Dispose(); + //TexturaRoca?.Dispose(); + //Effect?.Dispose(); + + RocaModel = null; + TexturaRoca = null; + Effect = null; + RocaBox = new BoundingBox(Vector3.Zero, Vector3.Zero); + //BoundingBoxes = null; + } + + private void DestruirBoundingBox() + { + if (BoundingBoxes != null) + { + BoundingBoxes.Remove(RocaBox); + } + } + + + private BoundingBox CreateBoundingBox(Model model, Matrix escala, Vector3 position) + { + var minPoint = Vector3.One * float.MaxValue; + var maxPoint = Vector3.One * float.MinValue; + + var transforms = new Matrix[model.Bones.Count]; + model.CopyAbsoluteBoneTransformsTo(transforms); + + foreach (var mesh in model.Meshes) + { + var meshParts = mesh.MeshParts; + foreach (var meshPart in meshParts) + { + var vertexBuffer = meshPart.VertexBuffer; + var declaration = vertexBuffer.VertexDeclaration; + var vertexSize = declaration.VertexStride / sizeof(float); + + var rawVertexBuffer = new float[vertexBuffer.VertexCount * vertexSize]; + vertexBuffer.GetData(rawVertexBuffer); + + for (var vertexIndex = 0; vertexIndex < rawVertexBuffer.Length; vertexIndex += vertexSize) + { + var transform = transforms[mesh.ParentBone.Index] * escala; + var vertex = new Vector3(rawVertexBuffer[vertexIndex], rawVertexBuffer[vertexIndex + 1], rawVertexBuffer[vertexIndex + 2]); + vertex = Vector3.Transform(vertex, transform); + minPoint = Vector3.Min(minPoint, vertex); + maxPoint = Vector3.Max(maxPoint, vertex); + } + } + } + + return new BoundingBox(minPoint + position, maxPoint + position); + } + } +} \ No newline at end of file diff --git a/TGC.MonoGame.TP/GameObjects/Props/Shack.cs b/TGC.MonoGame.TP/GameObjects/Props/Shack.cs new file mode 100644 index 000000000..2f517bdae --- /dev/null +++ b/TGC.MonoGame.TP/GameObjects/Props/Shack.cs @@ -0,0 +1,31 @@ +using Microsoft.Xna.Framework; +using Microsoft.Xna.Framework.Content; +using Microsoft.Xna.Framework.Graphics; +using ThunderingTanks.Collisions; + +namespace ThunderingTanks.Objects.Props +{ + public class Shack : GameObject + { + private Texture2D Texture2 { get; set; } + + public BoundingBox ShackBox; + public override void LoadContent(ContentManager Content, Effect effect) + { + Model = Content.Load(ContentFolder3D + "Snowy_Shack/Little_shack"); + Texture = Content.Load(ContentFolder3D + "Snowy_Shack/Little_shack_DefaultMaterial_BaseColor"); + Texture2 = Content.Load(ContentFolder3D + "Snowy_Shack/Little_shack_DefaultMaterial_Metallic"); + Effect = effect; + + foreach (ModelMesh mesh in Model.Meshes) + { + foreach (ModelMeshPart meshPart in mesh.MeshParts) + { + meshPart.Effect = Effect; + } + } + + ShackBox = CollisionsClass.CreateBoundingBox(Model, Matrix.CreateScale(2.5f), Position); + } + } +} diff --git a/TGC.MonoGame.TP/GameObjects/Props/Trees.cs b/TGC.MonoGame.TP/GameObjects/Props/Trees.cs new file mode 100644 index 000000000..12b5080c5 --- /dev/null +++ b/TGC.MonoGame.TP/GameObjects/Props/Trees.cs @@ -0,0 +1,88 @@ +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 System; +using System.Collections.Generic; +using System.Drawing; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace ThunderingTanks.Objects.Props +{ + public class Trees : GameObject + { + public List TreesModels { get; set; } + private ModelMesh modelMesh { get; set; } + + private Vector3 originalPosition; + + + public void LoadList(ContentManager content, Effect effect, SimpleTerrain terrain) + { + TreesModels = new List(); + Model = content.Load(ContentFolder3D + "64Trees/firs_1"); + Texture = content.Load(ContentFolder3D + "64Trees/nature_bark_fir_01_l_0001_b"); + Effect = effect; + + float terrainHeight = terrain.Height(Position.X, Position.Z); + Vector3 adjustedPosition = new Vector3(Position.X, terrainHeight - 400, Position.Z); + + MaxBox = new Vector3(adjustedPosition.X + 100, adjustedPosition.Y + 500, adjustedPosition.Z + 100); + MinBox = new Vector3(adjustedPosition.X - 100, adjustedPosition.Y, adjustedPosition.Z - 100); + + BoundingBox = new BoundingBox(MinBox, MaxBox); + + foreach (ModelMesh mesh in Model.Meshes) + { + foreach(ModelMeshPart meshPart in mesh.MeshParts) + { + meshPart.Effect = Effect; + } + + TreesModels.Add(mesh); + } + + Random random = new Random(); + modelMesh = TreesModels[random.Next(TreesModels.Count())]; + + + } + + public void Draw(Matrix view, Matrix projection, GraphicsDevice graphicsDevice, SimpleTerrain terrain) + { + + var originalRasterizerState = graphicsDevice.RasterizerState; + + var rasterizerState = new RasterizerState(); + rasterizerState.CullMode = CullMode.None; + + graphicsDevice.RasterizerState = rasterizerState; + + originalPosition = Position; + + float terrainHeight = terrain.Height(originalPosition.X, originalPosition.Z); + Vector3 adjustedPosition = new Vector3(originalPosition.X, terrainHeight-420, originalPosition.Z); + WorldMatrix = Matrix.CreateTranslation(adjustedPosition); + + foreach (Effect effect in modelMesh.Effects) + { + effect.Parameters["View"].SetValue(view); + effect.Parameters["Projection"].SetValue(projection); + } + + Effect.Parameters["ModelTexture"].SetValue(Texture); + Effect.Parameters["World"].SetValue(modelMesh.ParentBone.Transform * Matrix.CreateScale(4) * WorldMatrix); + + Effect.Parameters["EnableTrees"].SetValue(true); + modelMesh.Draw(); + Effect.Parameters["EnableTrees"].SetValue(false); + + graphicsDevice.RasterizerState = originalRasterizerState; + + } + + } +} diff --git a/TGC.MonoGame.TP/GameObjects/SkyBox.cs b/TGC.MonoGame.TP/GameObjects/SkyBox.cs new file mode 100644 index 000000000..0b2568838 --- /dev/null +++ b/TGC.MonoGame.TP/GameObjects/SkyBox.cs @@ -0,0 +1,104 @@ +using Microsoft.Xna.Framework; +using Microsoft.Xna.Framework.Graphics; +using Microsoft.Xna.Framework.Content; + +namespace ThunderingTanks.Objects +{ + /// + /// Handles all of the aspects of working with a SkyBox. + /// + public class SkyBox + { + + public const string ContentFolder3D = "Models/"; + public const string ContentFolderEffects = "Effects/"; + public const string ContentFolderTextures = "Textures/"; + + /// + /// Creates a new SkyBox + /// + /// The geometry to use for SkyBox. + /// The SkyBox texture to use. + /// The SkyBox fx to use. + /// The SkyBox fx to use. + public SkyBox(float size) + { + Size = size; + } + + /// + /// The size of the cube, used so that we can resize the box + /// for different sized environments. + /// + private float Size { get; set; } + + /// + /// The effect file that the SkyBox will use to render + /// + private Effect Effect { get; set; } + + /// + /// The actual SkyBox texture + /// + private TextureCube Texture { get; set; } + + /// + /// The SkyBox model, which will just be a cube + /// + public Model Model { get; set; } + + /// + /// Loads the SkyBox texture and effect. + /// + /// + public void LoadContent(ContentManager Content) + { + var skyBox = Content.Load(ContentFolder3D + "cube"); + var skyBoxTexture = Content.Load(ContentFolderTextures + "/skyboxes/mountain_skybox_hd"); + var skyBoxEffect = Content.Load(ContentFolderEffects + "SkyBox"); + + Model = skyBox; + Texture = skyBoxTexture; + Effect = skyBoxEffect; + } + + /// + /// Does the actual drawing of the SkyBox with our SkyBox effect. + /// There is no world matrix, because we're assuming the SkyBox won't + /// be moved around. The size of the SkyBox can be changed with the size + /// variable. + /// + /// The view matrix for the effect + /// The projection matrix for the effect + /// The position of the camera + public void Draw(Matrix view, Matrix projection, Vector3 cameraPosition) + { + + // Go through each pass in the effect, but we know there is only one... + foreach (var pass in Effect.CurrentTechnique.Passes) + { + pass.Apply(); + + // Draw all of the components of the mesh, but we know the cube really + // only has one mesh + foreach (var mesh in Model.Meshes) + { + // Assign the appropriate values to each of the parameters + foreach (var part in mesh.MeshParts) + { + part.Effect = Effect; + part.Effect.Parameters["World"].SetValue( + Matrix.CreateScale(Size) * Matrix.CreateTranslation(cameraPosition)); + part.Effect.Parameters["View"].SetValue(view); + part.Effect.Parameters["Projection"].SetValue(projection); + part.Effect.Parameters["SkyBoxTexture"].SetValue(Texture); + part.Effect.Parameters["CameraPosition"].SetValue(cameraPosition); + } + + // Draw the mesh with the SkyBox effect + mesh.Draw(); + } + } + } + } +} \ No newline at end of file diff --git a/TGC.MonoGame.TP/GameObjects/Tanks/EnemyTanks.cs b/TGC.MonoGame.TP/GameObjects/Tanks/EnemyTanks.cs new file mode 100644 index 000000000..2c421ae6d --- /dev/null +++ b/TGC.MonoGame.TP/GameObjects/Tanks/EnemyTanks.cs @@ -0,0 +1,199 @@ +using Microsoft.Xna.Framework.Graphics; +using Microsoft.Xna.Framework; +using System; +using System.Collections.Generic; +using Microsoft.Xna.Framework.Input; +using Microsoft.Xna.Framework.Content; +using ThunderingTanks.Cameras; +using ThunderingTanks.Collisions; + +namespace ThunderingTanks.Objects.Tanks +{ + public class EnemyTank : GameObject + { + + public ParticleSystem particleSystem; + + public Model Tanque { get; set; } + private Texture2D PanzerTexture { get; set; } + private Texture2D TrackTexture { get; set; } + public Vector3 PanzerPosition { get; set; } + public Matrix PanzerMatrix { get; set; } + + private Vector3 Direction = Vector3.Zero; + public float Rotation = 0; + + public BoundingBox TankBox { get; set; } + + public float TankVelocity { get; set; } + public float TankRotation { get; set; } + public List Bones { get; private set; } + public List Meshes { get; private set; } + public float FireRate { get; set; } + private float timeSinceLastShot = 0f; + + public float screenHeight; + public float screenWidth; + public float GunRotationFinal = 0; + public float GunElevation = 0; + + public float GunRotation { get; set; } + + public Matrix turretWorld { get; set; } + public Matrix cannonWorld { get; set; } + + public bool Stop { get; set; } = false; + + public float shootInterval; + public float lifeSpan; + public float life = 5; + private float trackOffset = 0; + + public EnemyTank(GraphicsDevice graphicsDevice) + { + turretWorld = Matrix.Identity; + cannonWorld = Matrix.Identity; + TankVelocity = 100f; + } + + public void LoadContent(ContentManager Content, GraphicsDevice graphicsDevice) + { + Tanque = Content.Load(ContentFolder3D + "M4/M4"); + PanzerTexture = Content.Load(ContentFolder3D + "M4/M4_Sherman"); + TrackTexture = Content.Load(ContentFolder3D + "M4/Grant_track"); + Effect = Content.Load(ContentFolderEffects + "BasicShader"); + + PanzerMatrix = Matrix.CreateTranslation(Position); + + MinBox = new(-200, 0, -300); + MaxBox = new(200, 250, 300); + TankBox = new BoundingBox(Position + MinBox, Position + MaxBox); + + //particleSystem = new ParticleSystem(graphicsDevice); + } + + public void Update(GameTime gameTime, Vector3 playerPosition, SimpleTerrain terrain, GraphicsDevice graphicsDevice, Camera camera) + { + float time = (float)gameTime.ElapsedGameTime.TotalSeconds; + timeSinceLastShot += time; + Vector3 screenPosition = graphicsDevice.Viewport.Project(Position, camera.Projection, camera.View, Matrix.Identity); + + Vector3 direction = playerPosition - Position; + + direction.Y = 0; + + var X = Position.X; + var Z = Position.Z; + + float terrainHeight = terrain.Height(X, Z); + + Position = new Vector3(Position.X, terrainHeight - 400, Position.Z); + + float distanceToPlayer = direction.Length(); + Direction = Vector3.Normalize(direction); + + if (distanceToPlayer < 2500f) + { + TankVelocity = 0f; + } + else if (Stop == true) + { + TankVelocity = 0f; + GunRotationFinal = 0f; + } + else + { + Rotation = (float)Math.Atan2(Direction.X, Direction.Z); + GunElevation = (float)Math.Atan2(playerPosition.Y - Position.Y, distanceToPlayer); + + GunRotationFinal = Rotation; + TankVelocity = 180f; + + LastPosition = Position; + + Position += Direction * TankVelocity * time; + if (Direction.Y > 0) + trackOffset += 0.1f; + else + trackOffset -= 0.1f; + + TankBox = new BoundingBox(Position + MinBox, Position + MaxBox); + + } + + PanzerMatrix = Matrix.CreateRotationY(Rotation) * Matrix.CreateTranslation(Position); + turretWorld = Matrix.CreateRotationY(GunRotationFinal) * Matrix.CreateTranslation(Position); + cannonWorld = Matrix.CreateScale(100f) * Matrix.CreateRotationX(GunElevation) * turretWorld; + } + + public void Draw(Matrix world, Matrix view, Matrix projection, GraphicsDevice _GraphicsDevice) + { + var rasterizerState = new RasterizerState(); + Effect.Parameters["View"].SetValue(view); + Effect.Parameters["Projection"].SetValue(projection); + + foreach (var mesh in Tanque.Meshes) + { + + foreach (ModelMeshPart part in mesh.MeshParts) + { + part.Effect = Effect; + } + + foreach (Effect effect in mesh.Effects) + { + effect.Parameters["View"].SetValue(view); + effect.Parameters["Projection"].SetValue(projection); + } + + if (mesh.Name.Equals("Turret")) + { + Effect.Parameters["ModelTexture"].SetValue(PanzerTexture); + Effect.Parameters["World"].SetValue(mesh.ParentBone.Transform * turretWorld); + } + else if (mesh.Name.Equals("Cannon")) + { + Effect.Parameters["ModelTexture"].SetValue(PanzerTexture); + Effect.Parameters["World"].SetValue(mesh.ParentBone.Transform * cannonWorld); + } + else if (mesh.Name.Equals("Treadmill1") || mesh.Name.Equals("Treadmill2")) + { + Effect.Parameters["ModelTexture"].SetValue(TrackTexture); + Effect.Parameters["World"].SetValue(mesh.ParentBone.Transform * PanzerMatrix); + Effect.Parameters["IsTrack"]?.SetValue(true); + Effect.Parameters["TrackOffset"].SetValue(trackOffset); + } + else + { + Effect.Parameters["ModelTexture"].SetValue(PanzerTexture); + Effect.Parameters["World"].SetValue(mesh.ParentBone.Transform * PanzerMatrix); + + Effect.Parameters["IsTrack"].SetValue(false); + } + + mesh.Draw(); + + } + } + + public void StopEnemy() + { + Stop = true; + } + + public Projectile Shoot() + { + Matrix ProjectileMatrix = Matrix.CreateTranslation(new Vector3(0f, 210f, 400f)) * Matrix.CreateRotationX(GunElevation) * turretWorld; + + float projectileScale = 1f; + float projectileSpeed = 15000f; + + Projectile projectile = new(ProjectileMatrix, GunRotationFinal, projectileSpeed, projectileScale); + + return projectile; + } + + + + } +} \ No newline at end of file diff --git a/TGC.MonoGame.TP/GameObjects/Tanks/Projectile.cs b/TGC.MonoGame.TP/GameObjects/Tanks/Projectile.cs new file mode 100644 index 000000000..0ba8b8c3c --- /dev/null +++ b/TGC.MonoGame.TP/GameObjects/Tanks/Projectile.cs @@ -0,0 +1,95 @@ +using Microsoft.Xna.Framework; +using Microsoft.Xna.Framework.Content; +using Microsoft.Xna.Framework.Graphics; +using ThunderingTanks.Collisions; + +namespace ThunderingTanks.Objects.Tanks +{ + public class Projectile : GameObject + { + + #region Projectile + private Model projectile { get; set; } + public BoundingBox ProjectileBox { get; set; } + public Matrix PositionMatrix { get; set; } + private Vector3 MovementVector { get; set; } + + public Vector3 PositionVector = new(0, 0, 0); + public Vector3 Direction { get; set; } + public float Speed { get; set; } + public float Scale { get; set; } + public float GunRotation { get; set; } + public bool WasShot { get; private set; } + #endregion + + public Projectile(Matrix matrix, float rotation, float speed, float scale) + { + PositionMatrix = matrix; + PositionVector = PositionMatrix.Translation; + + Direction = matrix.Backward; + Speed = speed; + + GunRotation = rotation; + + Scale = scale; + + } + + public override void LoadContent(ContentManager Content, Effect effect) + { + projectile = Content.Load(ContentFolder3D + "TankBullets/Apcr"); + + Texture = Content.Load(ContentFolder3D + "TankBullets/ApcrTexture"); + + Effect = effect; + + ProjectileBox = CollisionsClass.CreateBoundingBox(projectile, Matrix.CreateScale(0.5f), PositionVector); + + } + + public override void Update(GameTime gameTime) + { + float time = (float)gameTime.ElapsedGameTime.TotalSeconds; + + LastPosition = PositionVector; + PositionVector += Direction * Speed * time; + + PositionMatrix = Matrix.CreateRotationY(GunRotation) * Matrix.CreateTranslation(PositionVector); + + MovementVector = PositionVector - LastPosition; + ProjectileBox = new BoundingBox(ProjectileBox.Min + MovementVector, ProjectileBox.Max + MovementVector); + } + + public override void Draw(Matrix view, Matrix projection) + { + Matrix worldMatrix = Matrix.CreateScale(Scale) * Matrix.CreateRotationX(MathHelper.ToRadians(180)) * PositionMatrix; + + Effect.Parameters["View"].SetValue(view); + Effect.Parameters["Projection"].SetValue(projection); + + foreach (var mesh in projectile.Meshes) + { + foreach (ModelMeshPart part in mesh.MeshParts) + { + part.Effect = Effect; + } + + foreach (Effect effect in mesh.Effects) + { + effect.Parameters["View"].SetValue(view); + effect.Parameters["Projection"].SetValue(projection); + } + + Effect.Parameters["ModelTexture"].SetValue(Texture); + Effect.Parameters["World"].SetValue(mesh.ParentBone.Transform * worldMatrix); + + mesh.Draw(); + } + } + } +} + + + + diff --git a/TGC.MonoGame.TP/GameObjects/Tanks/Tank.cs b/TGC.MonoGame.TP/GameObjects/Tanks/Tank.cs new file mode 100644 index 000000000..131c26542 --- /dev/null +++ b/TGC.MonoGame.TP/GameObjects/Tanks/Tank.cs @@ -0,0 +1,345 @@ +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 ThunderingTanks.Collisions; + +namespace ThunderingTanks.Objects.Tanks +{ + public class Tank : GameObject + { + + #region Graphics + + private GraphicsDevice GraphicsDevice; + + public float screenHeight; + public float screenWidth; + #endregion + + #region Tank + + public Model Tanque { get; set; } + + private Texture2D PanzerTexture { get; set; } + private Texture2D TrackTexture { get; set; } + private float trackOffset1 = 0; + private float trackOffset2 = 0; + + public Matrix PanzerMatrix { get; set; } + private Matrix RotationMatrix { get; set; } + public Matrix TurretMatrix { get; set; } + public Matrix CannonMatrix { get; set; } + + public Vector3 CameraPosition { get; set; } + + public float TankVelocity { get; set; } + public float TankRotation { get; set; } + public float Rotation { get; set; } = 0f; + + public float FireRate { get; set; } + public float TimeSinceLastShot { get; set; } + + public float GunRotation { get; set; } + public float GunElevation { get; set; } + + public OrientedBoundingBox TankBox { get; set; } + public bool isColliding { get; set; } = false; + + + + public int MaxLife { get; } = 50; + public int CurrentLife { get; set; } + + public int NumberOfProyectiles { get; set; } + + #endregion + + #region Physics + + private readonly Vector3 Gravity = new(0f, -9.8f, 0); + + private Vector3 Spring1_Position; + private Vector3 Spring1_Direction; + private float Spring1_Length; + + private Vector3 Spring2_Position; + private Vector3 Spring2_Direction; + private float Spring2_Length; + + private Vector3 Spring3_Position; + private Vector3 Spring3_Direction; + private float Spring3_Length; + + private Vector3 Spring4_Position; + private Vector3 Spring4_Direction; + private float Spring4_Length; + + #endregion + + #region Sound + public SoundEffectInstance MovingTankSound { get; set; } + #endregion + + public float SensitivityFactor { get; set; } + + private bool _isPlaying = true; + public bool isDestroyed = false; + + public Tank() + { + TurretMatrix = Matrix.Identity; + CannonMatrix = Matrix.Identity; + + CurrentLife = MaxLife; + } + + public override void LoadContent(ContentManager Content, Effect effect) + { + + Tanque = Content.Load(ContentFolder3D + "Panzer/Panzer"); + + PanzerTexture = Content.Load(ContentFolder3D + "Panzer/PzVl_Tiger_I"); + TrackTexture = Content.Load(ContentFolder3D + "Panzer/PzVI_Tiger_I_track"); + + Effect = effect; + + MaxBox = new Vector3(200, 250, 300); + MinBox = new Vector3(-200, 0, -300); + BoundingBox = new BoundingBox(MinBox, MaxBox); + + TankBox = OrientedBoundingBox.FromAABB(BoundingBox); + + TimeSinceLastShot = FireRate; + } + + public void Update(GameTime gameTime, KeyboardState keyboardState, SimpleTerrain terrain) + { + float time = (float)gameTime.ElapsedGameTime.TotalSeconds; + TimeSinceLastShot += time; + + bool isMoving = false; + + var directionVector = Vector3.Zero; + + #region Movimiento + + if (keyboardState.IsKeyDown(Keys.W) && !isColliding) + { + directionVector -= Vector3.Forward * TankVelocity * time; + trackOffset1 -= 0.1f; + trackOffset2 -= 0.1f; + isMoving = true; + } + + if (keyboardState.IsKeyDown(Keys.S) && !isColliding) + { + directionVector += Vector3.Forward * TankVelocity * time; + trackOffset1 += 0.1f; + trackOffset2 += 0.1f; + isMoving = true; + } + + if (keyboardState.IsKeyDown(Keys.D)) + { + Rotation -= TankRotation * time; + trackOffset1 += 0.1f; + trackOffset2 -= 0.1f; + isMoving = true; + } + + if (keyboardState.IsKeyDown(Keys.A)) + { + Rotation += TankRotation * time; + trackOffset1 -= 0.1f; + trackOffset2 += 0.1f; + isMoving = true; + } + + if (isMoving) + { + if (!_isPlaying) + { + MovingTankSound.Play(); + _isPlaying = true; + } + } + else + { + MovingTankSound.Stop(); + } + + #endregion + + GunRotation -= GetRotationFromCursorX() * SensitivityFactor; + + GunElevation += GetElevationFromCursorY() * SensitivityFactor; + GunElevation = MathHelper.Clamp(GunElevation, MathHelper.ToRadians(-10), MathHelper.ToRadians(6)); + + Mouse.SetPosition((int)screenWidth / 2, (int)screenHeight / 2); + + #region MovimientoConRotacion + + RotationMatrix = Matrix.CreateRotationY(MathHelper.ToRadians(Rotation)); + + Vector3 rotatedDirection = Vector3.Transform(directionVector, RotationMatrix); + + var newPos = new Vector2(Position.X, Position.Z) + new Vector2(rotatedDirection.X, rotatedDirection.Z); + var X = newPos.X; + var Z = newPos.Y; + + #endregion + + float terrainHeight = terrain.Height(X, Z); + + Position = new Vector3(X, terrainHeight - 400, Z); + + PanzerMatrix = Matrix.CreateRotationY(MathHelper.ToRadians(Rotation)) * Matrix.CreateTranslation(Position); + TurretMatrix = Matrix.CreateRotationY(GunRotation) * Matrix.CreateTranslation(Position); + CannonMatrix = Matrix.CreateTranslation(new Vector3(-15f, 0f, 0f)) * Matrix.CreateRotationX(GunElevation) * Matrix.CreateRotationY(GunRotation) * Matrix.CreateTranslation(Position); + + TankBox.Center = Position + new Vector3(0f, 125f, 0f); + TankBox.Rotate(Matrix.CreateRotationY(MathHelper.ToRadians(Rotation))); + + CameraPosition = Position + new Vector3(0f, 500f, 0f); + + LastPosition = Position; + } + + public void Draw(Matrix view, Matrix projection, GraphicsDevice graphicsDevice) + { + + GraphicsDevice = graphicsDevice; + GraphicsDevice.RasterizerState = new RasterizerState() { CullMode = CullMode.None }; + GraphicsDevice.BlendState = BlendState.AlphaBlend; + + foreach (var mesh in Tanque.Meshes) + { + + foreach (ModelMeshPart part in mesh.MeshParts) + { + part.Effect = Effect; + } + + foreach (Effect effect in mesh.Effects) + { + effect.Parameters["View"].SetValue(view); + effect.Parameters["Projection"].SetValue(projection); + effect.CurrentTechnique = effect.Techniques["Impact"]; + } + + if (mesh.Name.Equals("Turret")) + { + Effect.Parameters["ModelTexture"].SetValue(PanzerTexture); + Effect.Parameters["World"].SetValue(mesh.ParentBone.Transform * TurretMatrix); + Effect.Parameters["IsTrack"].SetValue(false); + + } + else if (mesh.Name.Equals("Cannon")) + { + Effect.Parameters["ModelTexture"].SetValue(PanzerTexture); + Effect.Parameters["World"].SetValue(mesh.ParentBone.Transform * CannonMatrix); + Effect.Parameters["IsTrack"].SetValue(false); + + } + else if (mesh.Name.Equals("Treadmill2")) + { + Effect.Parameters["ModelTexture"].SetValue(TrackTexture); + Effect.Parameters["World"].SetValue(mesh.ParentBone.Transform * PanzerMatrix); + Effect.Parameters["IsTrack"]?.SetValue(true); + Effect.Parameters["TrackOffset"].SetValue(trackOffset1); + } + else if (mesh.Name.Equals("Treadmill1")) + { + Effect.Parameters["ModelTexture"].SetValue(TrackTexture); + Effect.Parameters["World"].SetValue(mesh.ParentBone.Transform * PanzerMatrix); + Effect.Parameters["IsTrack"]?.SetValue(true); + Effect.Parameters["TrackOffset"].SetValue(trackOffset2); + } + else + { + Effect.Parameters["ModelTexture"].SetValue(PanzerTexture); + Effect.Parameters["World"].SetValue(mesh.ParentBone.Transform * PanzerMatrix); + + Effect.Parameters["IsTrack"].SetValue(false); + } + + mesh.Draw(); + + } + + } + + // ------------ FUNCTIONS ------------ // + + /// + /// Genera un disparo de el tanque + /// + /// Projectile generado por el tanque + public Projectile Shoot() + { + if (TimeSinceLastShot >= FireRate) + { + Matrix ProjectileMatrix = Matrix.CreateTranslation(new Vector3(0f, 210f, 400f)) * Matrix.CreateRotationX(GunElevation) * TurretMatrix; + + float projectileScale = 1f; + float projectileSpeed = 15000f; + + Projectile projectile = new(ProjectileMatrix, GunRotation, projectileSpeed, projectileScale); // Crear el proyectil con la posición y dirección correcta + + TimeSinceLastShot = 0f; + NumberOfProyectiles -= 1; + + return projectile; + } + else + { + return null; + } + } + + /// + /// Resta vida al tanque + /// + /// Condicion de que el juego inicio + public void ReceiveDamage(ref bool _juegoIniciado) + { + CurrentLife -= 25; + if (CurrentLife <= 0) + { + isDestroyed = true; + _juegoIniciado = false; + } + + } + + /// + /// Valor X del movimiento del cursor + /// + /// Cantidad de Movimiento X + private float GetRotationFromCursorX() + { + screenWidth = GraphicsDevice.Viewport.Width; + + MouseState mouseState = Mouse.GetState(); + float mouseX = mouseState.X; + + return MathHelper.ToRadians(mouseX / screenWidth * 360f - 180f); + } + + /// + /// Valor Y del movimiento del cursor + /// + /// Cantidad de Movimiento Y + private float GetElevationFromCursorY() + { + screenHeight = GraphicsDevice.Viewport.Height; + + MouseState mouseState = Mouse.GetState(); + float mouseY = mouseState.Y; + + return MathHelper.ToRadians(mouseY / screenHeight * 180f - 90f); + } + } +} \ No newline at end of file diff --git a/TGC.MonoGame.TP/Geometries/CubePrimitive.cs b/TGC.MonoGame.TP/Geometries/CubePrimitive.cs new file mode 100644 index 000000000..434228bae --- /dev/null +++ b/TGC.MonoGame.TP/Geometries/CubePrimitive.cs @@ -0,0 +1,93 @@ +#region File Description + +//----------------------------------------------------------------------------- +// CubePrimitive.cs +// +// Microsoft XNA Community Game Platform +// Copyright (C) Microsoft Corporation. All rights reserved. +//----------------------------------------------------------------------------- + +#endregion File Description + +#region Using Statements + +using Microsoft.Xna.Framework; +using Microsoft.Xna.Framework.Graphics; + +#endregion Using Statements + +namespace ThunderingTanks.Geometries +{ + /// + /// Geometric primitive class for drawing cubes. + /// + public class CubePrimitive : GeometricPrimitive + { + public CubePrimitive(GraphicsDevice graphicsDevice) : this(graphicsDevice, 1, Color.White, Color.White, + Color.White, Color.White, Color.White, Color.White) + { + } + + public CubePrimitive(GraphicsDevice graphicsDevice, float size, Color color) : this(graphicsDevice, size, color, + color, color, color, color, color) + { + } + + /// + /// Constructs a new cube primitive, with the specified size. + /// + public CubePrimitive(GraphicsDevice graphicsDevice, float size, Color color1, Color color2, Color color3, + Color color4, Color color5, Color color6) + { + // A cube has six faces, each one pointing in a different direction. + Vector3[] normals = + { + // front normal + Vector3.UnitZ, + // back normal + -Vector3.UnitZ, + // right normal + Vector3.UnitX, + // left normal + -Vector3.UnitX, + // top normal + Vector3.UnitY, + // bottom normal + -Vector3.UnitY + }; + + Color[] colors = + { + color1, color2, color3, color4, color5, color6 + }; + + var i = 0; + // Create each face in turn. + foreach (var normal in normals) + { + // Get two vectors perpendicular to the face normal and to each other. + var side1 = new Vector3(normal.Y, normal.Z, normal.X); + var side2 = Vector3.Cross(normal, side1); + + // Six indices (two triangles) per face. + AddIndex(CurrentVertex + 0); + AddIndex(CurrentVertex + 1); + AddIndex(CurrentVertex + 2); + + AddIndex(CurrentVertex + 0); + AddIndex(CurrentVertex + 2); + AddIndex(CurrentVertex + 3); + + // Four vertices per face. + AddVertex((normal - side1 - side2) * size / 2, colors[i], normal); + AddVertex((normal - side1 + side2) * size / 2, colors[i], normal); + AddVertex((normal + side1 + side2) * size / 2, colors[i], normal); + AddVertex((normal + side1 - side2) * size / 2, colors[i], normal); + + i++; + } + + InitializePrimitive(graphicsDevice); + } + } +} \ No newline at end of file diff --git a/TGC.MonoGame.TP/Geometries/FullScreenQuad.cs b/TGC.MonoGame.TP/Geometries/FullScreenQuad.cs new file mode 100644 index 000000000..00ecbee01 --- /dev/null +++ b/TGC.MonoGame.TP/Geometries/FullScreenQuad.cs @@ -0,0 +1,79 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Numerics; +using System.Text; +using System.Threading.Tasks; +using Microsoft.Xna.Framework.Graphics; + +namespace ThunderingTanks.Geometries +{ + public class FullScreenQuad + { + private readonly GraphicsDevice device; + private IndexBuffer indexBuffer; + private VertexBuffer vertexBuffer; + + /// + /// Create a quad used in clip space + /// + /// Used to initialize and control the presentation of the graphics device. + public FullScreenQuad(GraphicsDevice device) + { + this.device = device; + CreateVertexBuffer(); + CreateIndexBuffer(); + } + + private void CreateVertexBuffer() + { + var vertices = new VertexPositionTexture[4]; + vertices[0].Position = new Vector3(-1f, -1f, 0f); + vertices[0].TextureCoordinate = new Vector2(0f, 1f); + vertices[1].Position = new Vector3(-1f, 1f, 0f); + vertices[1].TextureCoordinate = new Vector2(0f, 0f); + vertices[2].Position = new Vector3(1f, -1f, 0f); + vertices[2].TextureCoordinate = new Vector2(1f, 1f); + vertices[3].Position = new Vector3(1f, 1f, 0f); + vertices[3].TextureCoordinate = new Vector2(1f, 0f); + + vertexBuffer = new VertexBuffer(device, VertexPositionTexture.VertexDeclaration, 4, + BufferUsage.WriteOnly); + vertexBuffer.SetData(vertices); + } + + private void CreateIndexBuffer() + { + var indices = new ushort[6]; + + indices[0] = 0; + indices[1] = 1; + indices[2] = 3; + indices[3] = 0; + indices[4] = 3; + indices[5] = 2; + + indexBuffer = new IndexBuffer(device, IndexElementSize.SixteenBits, 6, BufferUsage.WriteOnly); + indexBuffer.SetData(indices); + } + + + public void Draw(Effect effect) + { + device.SetVertexBuffer(vertexBuffer); + device.Indices = indexBuffer; + + foreach (var pass in effect.CurrentTechnique.Passes) + { + pass.Apply(); + device.DrawIndexedPrimitives(PrimitiveType.TriangleList, 0, 0, 2); + } + } + + public void Dispose() + { + vertexBuffer.Dispose(); + indexBuffer.Dispose(); + } + } +} diff --git a/TGC.MonoGame.TP/Geometries/GeometricPrimitive.cs b/TGC.MonoGame.TP/Geometries/GeometricPrimitive.cs new file mode 100644 index 000000000..426b97a1d --- /dev/null +++ b/TGC.MonoGame.TP/Geometries/GeometricPrimitive.cs @@ -0,0 +1,174 @@ +#region File Description + +//----------------------------------------------------------------------------- +// GeometricPrimitive.cs +// +// Microsoft XNA Community Game Platform +// Copyright (C) Microsoft Corporation. All rights reserved. +//----------------------------------------------------------------------------- + +#endregion File Description + +#region Using Statements + +using System; +using System.Collections.Generic; +using Microsoft.Xna.Framework; +using Microsoft.Xna.Framework.Graphics; + +#endregion Using Statements + +namespace ThunderingTanks.Geometries +{ + /// + /// Base class for simple geometric primitive models. This provides a vertex buffer, an index buffer, plus methods for + /// drawing the model. Classes for specific types of primitive (CubePrimitive, SpherePrimitive, etc.) are derived from + /// this common base, and use the AddVertex and AddIndex methods to specify their geometry. + /// + public abstract class GeometricPrimitive : IDisposable + { + #region Fields + + // During the process of constructing a primitive model, vertex and index data is stored on the CPU in these managed lists. + public List Vertices { get; } = new List(); + + public List Indices { get; } = new List(); + + // Once all the geometry has been specified, the InitializePrimitive method copies the vertex and index data into these buffers, + // which store it on the GPU ready for efficient rendering. + private VertexBuffer VertexBuffer { get; set; } + + private IndexBuffer IndexBuffer { get; set; } + public BasicEffect Effect { get; set; } + + #endregion Fields + + #region Initialization + + /// + /// Adds a new vertex to the primitive model. This should only be called during the initialization process, before + /// InitializePrimitive. + /// + protected void AddVertex(Vector3 position, Color color, Vector3 normal) + { + Vertices.Add(new VertexPositionColorNormal(position, color, normal)); + } + + /// + /// Adds a new index to the primitive model. This should only be called during the initialization process, before + /// InitializePrimitive. + /// + protected void AddIndex(int index) + { + if (index > ushort.MaxValue) + throw new ArgumentOutOfRangeException(nameof(index)); + + Indices.Add((ushort) index); + } + + /// + /// Queries the index of the current vertex. This starts at zero, and increments every time AddVertex is called. + /// + protected int CurrentVertex => Vertices.Count; + + /// + /// Once all the geometry has been specified by calling AddVertex and AddIndex, this method copies the vertex and index + /// data into GPU format buffers, ready for efficient rendering. + /// + protected void InitializePrimitive(GraphicsDevice graphicsDevice) + { + // Create a vertex declaration, describing the format of our vertex data. + + // Create a vertex buffer, and copy our vertex data into it. + VertexBuffer = new VertexBuffer(graphicsDevice, typeof(VertexPositionColorNormal), Vertices.Count, + BufferUsage.None); + VertexBuffer.SetData(Vertices.ToArray()); + + // Create an index buffer, and copy our index data into it. + IndexBuffer = new IndexBuffer(graphicsDevice, typeof(ushort), Indices.Count, BufferUsage.None); + + IndexBuffer.SetData(Indices.ToArray()); + + // Create a BasicEffect, which will be used to render the primitive. + Effect = new BasicEffect(graphicsDevice); + Effect.VertexColorEnabled = true; + Effect.EnableDefaultLighting(); + } + + /// + /// Finalizer. + /// + ~GeometricPrimitive() + { + Dispose(false); + } + + /// + /// Frees resources used by this object. + /// + public void Dispose() + { + Dispose(true); + GC.SuppressFinalize(this); + } + + /// + /// Frees resources used by this object. + /// + protected virtual void Dispose(bool disposing) + { + if (!disposing) return; + VertexBuffer?.Dispose(); + IndexBuffer?.Dispose(); + Effect?.Dispose(); + } + + #endregion Initialization + + #region Draw + + /// + /// Draws the primitive model, using the specified effect. Unlike the other Draw overload where you just specify the + /// world/view/projection matrices and color, this method does not set any render states, so you must make sure all + /// states are set to sensible values before you call it. + /// + /// Used to set and query effects, and to choose techniques. + public void Draw(Effect effect) + { + var graphicsDevice = effect.GraphicsDevice; + + // Set our vertex declaration, vertex buffer, and index buffer. + graphicsDevice.SetVertexBuffer(VertexBuffer); + + graphicsDevice.Indices = IndexBuffer; + + foreach (var effectPass in effect.CurrentTechnique.Passes) + { + effectPass.Apply(); + + var primitiveCount = Indices.Count / 3; + + graphicsDevice.DrawIndexedPrimitives(PrimitiveType.TriangleList, 0, 0, primitiveCount); + } + } + + /// + /// Draw the box. + /// + /// The world matrix for this box. + /// The view matrix, normally from the camera. + /// The projection matrix, normally from the application. + public void Draw(Matrix world, Matrix view, Matrix projection) + { + // Set BasicEffect parameters. + Effect.World = world; + Effect.View = view; + Effect.Projection = projection; + + // Draw the model, using BasicEffect. + Draw(Effect); + } + + #endregion Draw + } +} \ No newline at end of file diff --git a/TGC.MonoGame.TP/Gizmos/Geometries/AxisLines.cs b/TGC.MonoGame.TP/Gizmos/Geometries/AxisLines.cs new file mode 100644 index 000000000..f0b5e283e --- /dev/null +++ b/TGC.MonoGame.TP/Gizmos/Geometries/AxisLines.cs @@ -0,0 +1,73 @@ +using Microsoft.Xna.Framework; +using Microsoft.Xna.Framework.Graphics; +using System; + +namespace ThunderingTanks.Gizmos.Geometries +{ + /// + /// Gizmo for drawing the Axis Lines of an application. + /// + class AxisLines + { + private const float AxisScreenOffset = 20f; + private const float AxisScreenDistance = 40f; + + private GraphicsDevice GraphicsDevice; + + private Model Model; + + private BasicEffect Effect; + + private Matrix BaseScaleTranslation { get; set; } + + /// + /// Constructs an AxisLines drawable object. + /// + /// The GraphicsDevice to bind the resources. + /// The Model of the AxisLines, loaded from content. + public AxisLines(GraphicsDevice device, Model model) + { + GraphicsDevice = device; + Model = model; + + foreach (var mesh in Model.Meshes) + foreach (var part in mesh.MeshParts) + Effect = (BasicEffect)part.Effect; + + Effect.Projection = Matrix.Identity; + Effect.View = Matrix.Identity; + Effect.World = Matrix.Identity; + + BaseScaleTranslation = + // Scale the arrows + Matrix.CreateScale(0.02f) * + // Translate them to the bottom left of the screen, and add a Z value to prevent clipping + Matrix.CreateTranslation(0.87f, -0.9f, 0.2f); + + Effect.EnableDefaultLighting(); + } + + /// + /// Sets the view matrix needed to draw the Axis Lines in the screen. + /// + /// The view matrix, generally from a camera. + public void SetView(Matrix view) + { + view.Translation = Vector3.Zero; + Effect.World = + // Use the View matrix, with no translation, to make the arrows face where the camera is pointing at + // Then multiply by the base Scale and Translation + view * BaseScaleTranslation; + } + + + /// + /// Draws the AxisLines + /// + public virtual void Draw() + { + foreach (var mesh in Model.Meshes) + mesh.Draw(); + } + } +} diff --git a/TGC.MonoGame.TP/Gizmos/Geometries/CubeGizmoGeometry.cs b/TGC.MonoGame.TP/Gizmos/Geometries/CubeGizmoGeometry.cs new file mode 100644 index 000000000..8f1070959 --- /dev/null +++ b/TGC.MonoGame.TP/Gizmos/Geometries/CubeGizmoGeometry.cs @@ -0,0 +1,72 @@ +using Microsoft.Xna.Framework; +using Microsoft.Xna.Framework.Graphics; + +namespace ThunderingTanks.Gizmos.Geometries +{ + /// + /// Gizmo for drawing Wire Cubes. + /// + class CubeGizmoGeometry : GizmoGeometry + { + private static Matrix PrecalculatedFrustumTransform = Matrix.CreateTranslation(Vector3.Backward * 0.5f) * Matrix.CreateScale(new Vector3(2f, 2f, 1f)); + + /// + /// Creates a Wire Cube. + /// + /// A GraphicsDevice to bind the geometry. + public CubeGizmoGeometry(GraphicsDevice graphicsDevice) : base(graphicsDevice) + { + var vertices = new VertexPosition[8] + { + new VertexPosition(new Vector3(0.5f, 0.5f, 0.5f)), + new VertexPosition(new Vector3(-0.5f, 0.5f, 0.5f)), + new VertexPosition(new Vector3(0.5f, -0.5f, 0.5f)), + new VertexPosition(new Vector3(-0.5f, -0.5f, 0.5f)), + new VertexPosition(new Vector3(0.5f, 0.5f, -0.5f)), + new VertexPosition(new Vector3(-0.5f, 0.5f, -0.5f)), + new VertexPosition(new Vector3(0.5f, -0.5f, -0.5f)), + new VertexPosition(new Vector3(-0.5f, -0.5f, -0.5f)) + }; + var indices = new ushort[24] + { + 0, 1, + 0, 2, + 1, 3, + 3, 2, + + 4, 5, + 4, 6, + 5, 7, + 7, 6, + + 0, 4, + 1, 5, + 2, 6, + 3, 7 + }; + InitializeVertices(vertices); + InitializeIndices(indices); + } + + /// + /// Calculates a World matrix for this cube. + /// + /// The position in World space. + /// The scale of the cube. + /// The calculated World matrix. + public static Matrix CalculateWorld(Vector3 origin, Vector3 size) + { + return Matrix.CreateScale(size) * Matrix.CreateTranslation(origin); + } + + /// + /// Calculates a World matrix for a frustum. + /// + /// The ViewProjection matrix, generally from a camera or an application. + /// The calculated World matrix. + public static Matrix CalculateFrustumWorld(Matrix viewProjection) + { + return PrecalculatedFrustumTransform * Matrix.Invert(viewProjection); + } + } +} diff --git a/TGC.MonoGame.TP/Gizmos/Geometries/CylinderGizmoGeometry.cs b/TGC.MonoGame.TP/Gizmos/Geometries/CylinderGizmoGeometry.cs new file mode 100644 index 000000000..f22008830 --- /dev/null +++ b/TGC.MonoGame.TP/Gizmos/Geometries/CylinderGizmoGeometry.cs @@ -0,0 +1,88 @@ +using System; +using System.Linq; +using Microsoft.Xna.Framework; +using Microsoft.Xna.Framework.Graphics; + +namespace ThunderingTanks.Gizmos.Geometries +{ + /// + /// Gizmo for drawing Wire Cylinders. + /// + class CylinderGizmoGeometry : RadialGizmoGeometry + { + /// + /// Creates a Wire Cylinder with a number of subdivisions for the top and bottom. + /// + /// The device to bind geometry to. + /// The number of subdivisions to + public CylinderGizmoGeometry(GraphicsDevice device, int subdivisions) : base(device) + { + var positions = GeneratePolygonPositions(subdivisions); + var originalIndices = GeneratePolygonIndices(subdivisions); + + var subdivisionsTimesTwo = subdivisions * 2; + + // Lines for each circle, and four lines joining them + var indices = new ushort[subdivisions * 6 + 8]; + + Array.Copy(originalIndices, 0, indices, 0, subdivisionsTimesTwo); + Array.Copy(originalIndices.Select(index => (ushort)(index + subdivisions)).ToArray(), 0, indices, subdivisionsTimesTwo, subdivisionsTimesTwo); + Array.Copy(originalIndices.Select(index => (ushort)(index + subdivisionsTimesTwo)).ToArray(), 0, indices, subdivisionsTimesTwo * 2, subdivisionsTimesTwo); + + var index = subdivisions * 6; + var firstQuadrant = (ushort)(subdivisions / 4); + var firstQuadrantAdded = (ushort)(firstQuadrant + subdivisions); + var secondQuadrant = (ushort)(subdivisions / 2); + var secondQuadrantAdded = (ushort)(secondQuadrant + subdivisions); + var thirdQuadrant = (ushort)(firstQuadrant + secondQuadrant); + var thirdQuadrantAdded = (ushort)(thirdQuadrant + subdivisions); + + // Joining lines + indices[index] = 0; + index++; + indices[index] = (ushort)subdivisions; + index++; + indices[index] = firstQuadrant; + index++; + indices[index] = firstQuadrantAdded; + index++; + indices[index] = secondQuadrant; + index++; + indices[index] = secondQuadrantAdded; + index++; + indices[index] = thirdQuadrant; + index++; + indices[index] = thirdQuadrantAdded; + index++; + + var vertices = new VertexPosition[subdivisions * 3]; + positions + .Select(position => new VertexPosition(new Vector3(position.X, 1f, position.Y))) + .ToArray() + .CopyTo(vertices, 0); + + Array.Copy(positions + .Select(position => new VertexPosition(new Vector3(position.X, -1f, position.Y))) + .ToArray(), 0, vertices, subdivisions, subdivisions); + + Array.Copy(positions + .Select(position => new VertexPosition(new Vector3(position.X, 0f, position.Y))) + .ToArray(), 0, vertices, subdivisionsTimesTwo, subdivisions); + + InitializeVertices(vertices); + InitializeIndices(indices); + } + + /// + /// Calculates the World matrix for the Cylinder. Note that is initially XZ oriented. + /// + /// The position in world space. + /// The rotation of the Cylinder. + /// The scale of the Cylinder. + /// The calculated World matrix + public static Matrix CalculateWorld(Vector3 origin, Matrix rotation, Vector3 scale) + { + return Matrix.CreateScale(scale) * rotation * Matrix.CreateTranslation(origin); + } + } +} diff --git a/TGC.MonoGame.TP/Gizmos/Geometries/DiskGizmoGeometry.cs b/TGC.MonoGame.TP/Gizmos/Geometries/DiskGizmoGeometry.cs new file mode 100644 index 000000000..2defa555b --- /dev/null +++ b/TGC.MonoGame.TP/Gizmos/Geometries/DiskGizmoGeometry.cs @@ -0,0 +1,64 @@ +using System; +using System.Linq; +using Microsoft.Xna.Framework; +using Microsoft.Xna.Framework.Graphics; + +namespace ThunderingTanks.Gizmos.Geometries +{ + /// + /// Gizmo for drawing Wire Disks. + /// + class DiskGizmoGeometry : RadialGizmoGeometry + { + /// + /// Creates a Wire Disk geometry. + /// + /// The GraphicsDevice to bind the geometry. + /// The amount of subdivisions the wire disk will take when forming a circle. + public DiskGizmoGeometry(GraphicsDevice graphicsDevice, int subdivisions) : base(graphicsDevice) + { + var positions = GeneratePolygonPositions(subdivisions); + var originalIndices = GeneratePolygonIndices(subdivisions); + + var subdivisionsTimesTwo = subdivisions * 2; + + var indices = new ushort[subdivisionsTimesTwo]; + var vertices = new VertexPosition[subdivisions]; + + Array.Copy(originalIndices, 0, indices, 0, subdivisionsTimesTwo); + + Array.Copy(positions + .Select(position => new VertexPosition(new Vector3(position.Y, position.X, 0f))) + .ToArray(), 0, vertices, 0, subdivisions); + + InitializeVertices(vertices); + InitializeIndices(indices); + } + + + /// + /// Calculates the World matrix for the Disk. Note that is initially XZ oriented. + /// + /// The position in world space. + /// The normal of the Disk. The circle will face this vector. + /// The radius of the Disk. + /// The calculated World matrix + public static Matrix CalculateWorld(Vector3 origin, Vector3 normal, float radius) + { + Matrix rotationAndTranslation; + // Check if +Z or -Z. In that case, no need to rotate + // (also the view matrix is broken in those cases) + var distanceToZAxis = -MathF.Abs(normal.Z) + 1.0f; + if (distanceToZAxis < float.Epsilon) + { + rotationAndTranslation = Matrix.CreateTranslation(origin); + } + else + { + rotationAndTranslation = Matrix.Invert(Matrix.CreateLookAt(origin, origin + normal, Vector3.Backward)); + } + + return Matrix.CreateScale(radius) * rotationAndTranslation; + } + } +} diff --git a/TGC.MonoGame.TP/Gizmos/Geometries/GizmoGeometry.cs b/TGC.MonoGame.TP/Gizmos/Geometries/GizmoGeometry.cs new file mode 100644 index 000000000..e1ac545f7 --- /dev/null +++ b/TGC.MonoGame.TP/Gizmos/Geometries/GizmoGeometry.cs @@ -0,0 +1,75 @@ +using Microsoft.Xna.Framework.Graphics; + +namespace ThunderingTanks.Gizmos.Geometries +{ + /// + /// Gizmo that is drawn using non-user indexed line lists. + /// + abstract class GizmoGeometry + { + protected GraphicsDevice GraphicsDevice; + + protected VertexBuffer VertexBuffer; + + protected IndexBuffer IndexBuffer; + + private int PrimitiveCount; + + /// + /// Creates a Gizmo Geometry. + /// + /// Graphics Device to bind the geometry to, + public GizmoGeometry(GraphicsDevice device) + { + GraphicsDevice = device; + } + + /// + /// Initializes the Vertex Buffer using an array of vertices in local space. + /// + /// An array of vertices in local space. + protected void InitializeVertices(VertexPosition[] positions) + { + VertexBuffer = new VertexBuffer(GraphicsDevice, typeof(VertexPosition), positions.Length, BufferUsage.WriteOnly); + VertexBuffer.SetData(positions); + } + + /// + /// Initializes the Index Buffer. + /// + /// The indices that points to the line vertices. + protected void InitializeIndices(ushort[] indices) + { + IndexBuffer = new IndexBuffer(GraphicsDevice, IndexElementSize.SixteenBits, indices.Length, BufferUsage.WriteOnly); + IndexBuffer.SetData(indices); + + PrimitiveCount = indices.Length / 2; + } + + /// + /// Binds the geometry to the Graphics Device. + /// + public virtual void Bind() + { + GraphicsDevice.SetVertexBuffer(VertexBuffer); + GraphicsDevice.Indices = IndexBuffer; + } + + /// + /// Draws the geometry. Bind must be called first. + /// + public virtual void Draw() + { + GraphicsDevice.DrawIndexedPrimitives(PrimitiveType.LineList, 0, 0, PrimitiveCount); + } + + /// + /// Disposes the created geometry. + /// + public void Dispose() + { + VertexBuffer.Dispose(); + IndexBuffer.Dispose(); + } + } +} diff --git a/TGC.MonoGame.TP/Gizmos/Geometries/LineSegmentGizmoGeometry.cs b/TGC.MonoGame.TP/Gizmos/Geometries/LineSegmentGizmoGeometry.cs new file mode 100644 index 000000000..577138b95 --- /dev/null +++ b/TGC.MonoGame.TP/Gizmos/Geometries/LineSegmentGizmoGeometry.cs @@ -0,0 +1,41 @@ +using Microsoft.Xna.Framework; +using Microsoft.Xna.Framework.Graphics; + +namespace ThunderingTanks.Gizmos.Geometries +{ + /// + /// Gizmo for drawing lines. + /// + class LineSegmentGizmoGeometry : GizmoGeometry + { + /// + /// Creates a wire Line Segment. + /// + /// Graphics Device to bind the geometry to. + public LineSegmentGizmoGeometry(GraphicsDevice graphicsDevice) : base(graphicsDevice) + { + var vertices = new VertexPosition[2] + { + new VertexPosition(Vector3.Zero), + new VertexPosition(Vector3.One), + }; + var indices = new ushort[2] { 0, 1 }; + InitializeVertices(vertices); + InitializeIndices(indices); + } + + /// + /// Calculates the World matrix for the Line. + /// + /// The origin point of the Line in World space. + /// The destination point of the Line in World space. + /// The calculated World matrix + public static Matrix CalculateWorld(Vector3 origin, Vector3 destination) + { + var scale = destination - origin; + return Matrix.CreateScale(scale) * Matrix.CreateTranslation(origin); + } + + + } +} diff --git a/TGC.MonoGame.TP/Gizmos/Geometries/PolyLineGizmoGeometry.cs b/TGC.MonoGame.TP/Gizmos/Geometries/PolyLineGizmoGeometry.cs new file mode 100644 index 000000000..a6012b07b --- /dev/null +++ b/TGC.MonoGame.TP/Gizmos/Geometries/PolyLineGizmoGeometry.cs @@ -0,0 +1,46 @@ +using System.Linq; +using Microsoft.Xna.Framework; +using Microsoft.Xna.Framework.Graphics; + +namespace ThunderingTanks.Gizmos.Geometries +{ + /// + /// Gizmo for drawing Poly-Lines. + /// + class PolyLineGizmoGeometry + { + private GraphicsDevice GraphicsDevice; + private short[] Indices; + + /// + /// Creates a wire PolyLine. + /// + /// Graphics Device to bind the geometry to. + public PolyLineGizmoGeometry(GraphicsDevice graphicsDevice) + { + GraphicsDevice = graphicsDevice; + Indices = new short[1000]; + Indices[0] = 0; + for (short index = 1; index < 999; index += 2) + { + Indices[index] = index; + Indices[index + 1] = index; + } + } + + /// + /// Draws the Poly-Line using a set of points in World space. The continuous line will travel through these. + /// + /// Points in World space. + public void Draw(Vector3[] points) + { + var vertices = points.Select(point => new VertexPosition(point)).ToArray(); + + var primitiveCount = vertices.Length - 1; + var indexCount = primitiveCount * 2; + var indices = Indices.Take(indexCount).ToArray(); + + GraphicsDevice.DrawUserIndexedPrimitives(PrimitiveType.LineList, vertices, 0, vertices.Length, indices, 0, primitiveCount); + } + } +} diff --git a/TGC.MonoGame.TP/Gizmos/Geometries/RadialGizmoGeometry.cs b/TGC.MonoGame.TP/Gizmos/Geometries/RadialGizmoGeometry.cs new file mode 100644 index 000000000..7c42e8c26 --- /dev/null +++ b/TGC.MonoGame.TP/Gizmos/Geometries/RadialGizmoGeometry.cs @@ -0,0 +1,67 @@ +using System; +using Microsoft.Xna.Framework; +using Microsoft.Xna.Framework.Graphics; + +namespace ThunderingTanks.Gizmos.Geometries +{ + /// + /// Abstract class for any geometry that contains a circle. + /// + internal abstract class RadialGizmoGeometry : GizmoGeometry + { + /// + /// Creates a Radial Geometry, which contains a radial wire shape. + /// + /// Graphics Device to bind the geometry to. + protected RadialGizmoGeometry(GraphicsDevice device) : base(device) + { + + } + + /// + /// Generates a set of positions in a radial circle, given a number of subdivisions. + /// + /// The number of subdivisions that the circle will contain. + /// An array of positions in two dimensions describing a circle with the given subdivisions. + protected Vector2[] GeneratePolygonPositions(int subdivisions) + { + var positions = new Vector2[subdivisions]; + + var offset = 0f; + + // Odd? Then start at 90 degrees + if (subdivisions % 2 == 1) + offset = MathHelper.PiOver2; + + var increment = MathHelper.TwoPi / subdivisions; + for (ushort index = 0; index < subdivisions; index++) + { + positions[index] = new Vector2(MathF.Cos(offset), MathF.Sin(offset)); + offset += increment; + } + + return positions; + } + + /// + /// Generates the indices that relates the positions of a circle, creating the lines between them. + /// + /// The number of subdivisions that the circle contains. + /// An array of indices, in pairs, joining points to form lines of a circle. + protected ushort[] GeneratePolygonIndices(int subdivisions) + { + var subdivisionsTimesTwo = subdivisions * 2; + var indices = new ushort[subdivisionsTimesTwo]; + + for (ushort index = 0; index < subdivisions; index++) + { + indices[index * 2] = index; + indices[index * 2 + 1] = (ushort)(index + 1); + } + + // Override the last index, close the loop + indices[subdivisionsTimesTwo - 1] = 0; + return indices; + } + } +} diff --git a/TGC.MonoGame.TP/Gizmos/Geometries/SphereGizmoGeometry.cs b/TGC.MonoGame.TP/Gizmos/Geometries/SphereGizmoGeometry.cs new file mode 100644 index 000000000..f8ad8dd97 --- /dev/null +++ b/TGC.MonoGame.TP/Gizmos/Geometries/SphereGizmoGeometry.cs @@ -0,0 +1,60 @@ +using System; +using System.Linq; +using Microsoft.Xna.Framework; +using Microsoft.Xna.Framework.Graphics; + +namespace ThunderingTanks.Gizmos.Geometries +{ + /// + /// Gizmo for drawing Wire Spheres. + /// + class SphereGizmoGeometry : RadialGizmoGeometry + { + /// + /// Constructs a Wire Sphere. + /// + /// Graphics Device to bind the geometry to. + /// The amount of the subdivisions each sphere ring will have. + public SphereGizmoGeometry(GraphicsDevice graphicsDevice, int subdivisions) : base(graphicsDevice) + { + var positions = GeneratePolygonPositions(subdivisions); + var originalIndices = GeneratePolygonIndices(subdivisions); + + var subdivisionsTimesTwo = subdivisions * 2; + var indices = new ushort[subdivisions * 6]; + + Array.Copy(originalIndices, 0, indices, 0, subdivisionsTimesTwo); + Array.Copy(originalIndices.Select(index => (ushort)(index + subdivisions)).ToArray(), 0, indices, subdivisionsTimesTwo, subdivisionsTimesTwo); + Array.Copy(originalIndices.Select(index => (ushort)(index + subdivisionsTimesTwo)).ToArray(), 0, indices, subdivisionsTimesTwo * 2, subdivisionsTimesTwo); + + + var vertices = new VertexPosition[subdivisions * 3]; + positions + .Select(position => new VertexPosition(new Vector3(position, 0f))) + .ToArray() + .CopyTo(vertices, 0); + + Array.Copy(positions + .Select(position => new VertexPosition(new Vector3(position.Y, 0f, position.X))) + .ToArray(), 0, vertices, subdivisions, subdivisions); + + Array.Copy(positions + .Select(position => new VertexPosition(new Vector3(0f, position.Y, position.X))) + .ToArray(), 0, vertices, subdivisionsTimesTwo, subdivisions); + + InitializeVertices(vertices); + InitializeIndices(indices); + } + + /// + /// Calculates the World matrix for the Sphere. + /// + /// The position in world space. + /// The scale of the Sphere. + /// The calculated World matrix + public static Matrix CalculateWorld(Vector3 origin, Vector3 size) + { + return Matrix.CreateScale(size) * Matrix.CreateTranslation(origin); + } + } +} diff --git a/TGC.MonoGame.TP/Gizmos/Gizmos.cs b/TGC.MonoGame.TP/Gizmos/Gizmos.cs new file mode 100644 index 000000000..fb81e3050 --- /dev/null +++ b/TGC.MonoGame.TP/Gizmos/Gizmos.cs @@ -0,0 +1,438 @@ +using System.Collections.Generic; +using Microsoft.Xna.Framework; +using Microsoft.Xna.Framework.Content; +using Microsoft.Xna.Framework.Graphics; +using ThunderingTanks.Collisions; +using ThunderingTanks.Gizmos.Geometries; + +namespace ThunderingTanks.Gizmos +{ + /// + /// Renders Gizmos + /// + public class Gizmoss + { + /// + /// Creates a GizmosRenderer. + /// + public Gizmoss() + { + NoDepth = new DepthStencilState(); + NoDepth.DepthBufferEnable = false; + NoDepth.DepthBufferFunction = CompareFunction.Always; + } + + private AxisLines AxisLines { get; set; } + + private EffectPass BackgroundPass { get; set; } + + private Color BaseColor { get; set; } + private EffectParameter ColorParameter { get; set; } + private ContentManager Content { get; set; } + private CubeGizmoGeometry Cube { get; set; } + private CylinderGizmoGeometry Cylinder { get; set; } + private DiskGizmoGeometry Disk { get; set; } + + private Dictionary>> DrawInstances { get; } = + new Dictionary>>(); + + private Effect Effect { get; set; } + private EffectPass ForegroundPass { get; set; } + + private GraphicsDevice GraphicsDevice { get; set; } + + private LineSegmentGizmoGeometry LineSegment { get; set; } + + private DepthStencilState NoDepth { get; } + private PolyLineGizmoGeometry PolyLine { get; set; } + private Dictionary> PolyLinesToDraw { get; } = new Dictionary>(); + private Matrix Projection { get; set; } + private SphereGizmoGeometry Sphere { get; set; } + + private Matrix View { get; set; } + private Matrix ViewProjection { get; set; } + private EffectParameter WorldViewProjectionParameter { get; set; } + + + public bool Enabled { get; set; } = true; + + /// + /// Loads all the content necessary for drawing Gizmos. + /// + /// The GraphicsDevice to use when drawing. It is also used to bind buffers. + /// The ContentManager to manage Gizmos resources. + public void LoadContent(GraphicsDevice device, ContentManager content) + { + GraphicsDevice = device; + + Content = content; + + Effect = Content.Load("Effects/Gizmos"); + + BackgroundPass = Effect.CurrentTechnique.Passes["Background"]; + ForegroundPass = Effect.CurrentTechnique.Passes["Foreground"]; + WorldViewProjectionParameter = Effect.Parameters["WorldViewProjection"]; + ColorParameter = Effect.Parameters["Color"]; + + LineSegment = new LineSegmentGizmoGeometry(GraphicsDevice); + Cube = new CubeGizmoGeometry(GraphicsDevice); + Sphere = new SphereGizmoGeometry(GraphicsDevice, 20); + PolyLine = new PolyLineGizmoGeometry(GraphicsDevice); + Disk = new DiskGizmoGeometry(GraphicsDevice, 20); + Cylinder = new CylinderGizmoGeometry(GraphicsDevice, 20); + AxisLines = new AxisLines(GraphicsDevice, Content.Load("3D/geometries/arrow")); + + DrawInstances[LineSegment] = new Dictionary>(); + DrawInstances[Sphere] = new Dictionary>(); + DrawInstances[Cube] = new Dictionary>(); + DrawInstances[Disk] = new Dictionary>(); + DrawInstances[Cylinder] = new Dictionary>(); + } + + /// + /// Adds a draw instance specifying the geometry, its color and the world matrix to use when drawing. + /// + /// The GizmoGeometry to be drawn. + /// The color of the geometry. + /// The world matrix to be used when drawing. + /// + public void DrawOrientedCube(Vector3 origin, Matrix orientation, Vector3 size) + { + DrawOrientedCube(origin, orientation, size, BaseColor); + } + public void DrawOrientedCube(Vector3 origin, Matrix orientation, Vector3 size, Color color) + { + var world = Matrix.CreateScale(size) * orientation * Matrix.CreateTranslation(origin); + AddDrawInstance(Cube, color, world); + } + private void AddDrawInstance(GizmoGeometry type, Color color, Matrix world) + { + var instancesByType = DrawInstances[type]; + instancesByType.TryAdd(color, new List()); + instancesByType[color].Add(world * ViewProjection); + } + + /// + /// Draws a line between the points origin and destination using the Gizmos color. + /// + /// The origin of the line. + /// The final point of the line. + public void DrawLine(Vector3 origin, Vector3 destination) + { + DrawLine(origin, destination, BaseColor); + } + + /// + /// Draws a line between the points origin and destination using the specified color. + /// + /// The origin of the line. + /// The final point of the line. + /// The color of the line. + public void DrawLine(Vector3 origin, Vector3 destination, Color color) + { + var world = LineSegmentGizmoGeometry.CalculateWorld(origin, destination); + AddDrawInstance(LineSegment, color, world); + } + + /// + /// Draws a wire cube with an origin and size using the Gizmos color. + /// + /// The position of the cube. + /// The size of the cube. + public void DrawCube(Vector3 origin, Vector3 size) + { + DrawCube(origin, size, BaseColor); + } + + /// + /// Draws a wire cube with a World matrix using the Gizmos color. + /// + /// The World matrix of the cube. + public void DrawCube(Matrix world) + { + DrawCube(world, BaseColor); + } + + /// + /// Draws a wire cube with a World matrix using the specified color. + /// + /// The World matrix of the cube. + /// The color of the cube. + public void DrawCube(Matrix world, Color color) + { + AddDrawInstance(Cube, color, world); + } + + /// + /// Draws a wire cube with an origin and size using the specified color. + /// + /// The position of the cube. + /// The size of the cube. + /// The color of the cube. + public void DrawCube(Vector3 origin, Vector3 size, Color color) + { + var world = CubeGizmoGeometry.CalculateWorld(origin, size); + AddDrawInstance(Cube, color, world); + } + + /// + /// Draws a wire sphere with an origin and size using the Gizmos color. + /// + /// The position of the sphere. + /// The size of the sphere. + public void DrawSphere(Vector3 origin, Vector3 size) + { + DrawSphere(origin, size, BaseColor); + } + + /// + /// Draws a wire sphere with an origin and size using the specified color. + /// + /// The position of the sphere. + /// The size of the sphere. + /// The color of the sphere. + public void DrawSphere(Vector3 origin, Vector3 size, Color color) + { + var world = SphereGizmoGeometry.CalculateWorld(origin, size); + AddDrawInstance(Sphere, color, world); + } + + /// + /// Draws a contiguous line joining the given points and using the Gizmos color. + /// + /// The positions of the poly-line points in world space. + public void DrawPolyLine(Vector3[] points) + { + DrawPolyLine(points, BaseColor); + } + + /// + /// Draws a contiguous line joining the given points and using the specified color. + /// + /// The positions of the poly-line points in world space. + /// The color of the poly-line. + public void DrawPolyLine(Vector3[] points, Color color) + { + PolyLinesToDraw.TryAdd(color, new List()); + PolyLinesToDraw[color].Add(points); + } + + /// + /// Draws a wire frustum -ViewProjection matrix- using the Gizmos color. + /// + /// The ViewProjection matrix of a virtual camera to draw its frustum. + public void DrawFrustum(Matrix viewProjection) + { + DrawFrustum(viewProjection, BaseColor); + } + + /// + /// Draws a wire frustum -ViewProjection matrix- using the specified color. + /// + /// The ViewProjection matrix of a virtual camera to draw its frustum. + /// The color of the frustum. + public void DrawFrustum(Matrix viewProjection, Color color) + { + var world = CubeGizmoGeometry.CalculateFrustumWorld(viewProjection); + AddDrawInstance(Cube, color, world); + } + + /// + /// Draws a wire circle with an origin and normal direction using the Gizmos color. + /// + /// The position of the disk. + /// The normal direction of the disk, assumed normalized. It will face this vector. + /// The radius of the disk in units. + public void DrawDisk(Vector3 origin, Vector3 normal, float radius) + { + DrawDisk(origin, normal, radius, BaseColor); + } + + /// + /// Draws a wire disk (a circle) with an origin and normal direction using the specified color. + /// + /// The position of the disk. + /// The normal direction of the disk, assumed normalized. It will face this vector. + /// The radius of the disk in units. + /// The color of the disk. + public void DrawDisk(Vector3 origin, Vector3 normal, float radius, Color color) + { + var world = DiskGizmoGeometry.CalculateWorld(origin, normal, radius); + AddDrawInstance(Disk, color, world); + } + + /// + /// Draws a wire cylinder with an origin, rotation and size using the Gizmos color. + /// + /// The position of the cylinder. + /// A rotation matrix to set the orientation of the cylinder. The cylinder is by default XZ aligned. + /// The size of the cylinder. + public void DrawCylinder(Vector3 origin, Matrix rotation, Vector3 size) + { + DrawCylinder(origin, rotation, size, BaseColor); + } + + /// + /// Draws a wire cylinder with an origin, rotation and size using the specified color. + /// + /// The position of the cylinder. + /// A rotation matrix to set the orientation of the cylinder. The cylinder is by default XZ aligned. + /// The size of the cylinder. + /// The color of the cylinder. + public void DrawCylinder(Vector3 origin, Matrix rotation, Vector3 size, Color color) + { + var world = CylinderGizmoGeometry.CalculateWorld(origin, rotation, size); + AddDrawInstance(Cylinder, color, world); + } + + /// + /// Draws a wire cylinder with a World matrix using the Gizmos color. + /// + /// The World matrix of the cylinder. + public void DrawCylinder(Matrix world) + { + DrawCylinder(world, BaseColor); + } + + /// + /// Draws a wire cylinder with a World matrix using the specified color. + /// + /// The World matrix of the cylinder. + /// The color of the cylinder. + public void DrawCylinder(Matrix world, Color color) + { + AddDrawInstance(Cylinder, color, world); + } + + /// + /// Sets the Gizmos color. All Gizmos drawn after are going to use this color if they do not specify one. + /// + /// The Gizmos color to set. + public void SetColor(Color color) + { + BaseColor = color; + } + + /// + /// Updates the View and Projection matrices. Should be called on an Update loop after the camera is updated. + /// + /// The View matrix of a camera. + /// The Projection matrix of a camera or a viewport. + public void UpdateViewProjection(Matrix view, Matrix projection) + { + View = view; + Projection = projection; + ViewProjection = View * Projection; + AxisLines.SetView(view); + } + + /// + /// Effectively draws the geometry using the parameters from past draw calls. Should be used after calling the other + /// draw methods. + /// + public void Draw() + { + if (!Enabled) + return; + + // Save our depth state, then use ours + var depth = GraphicsDevice.DepthStencilState; + GraphicsDevice.DepthStencilState = NoDepth; + + DrawBaseGizmosGeometries(BackgroundPass); + DrawPolyLines(BackgroundPass); + + // Restore our depth + GraphicsDevice.DepthStencilState = depth; + + // Draw our foreground geometry + DrawBaseGizmosGeometries(ForegroundPass); + DrawPolyLines(ForegroundPass); + + AxisLines.Draw(); + + CleanDrawInstances(); + } + + /// + /// Draws all Gizmos that are sub-classes of GizmoGeometry. + /// + /// The pass from an effect to draw the geometry with. + private void DrawBaseGizmosGeometries(EffectPass pass) + { + var count = 0; + List matrices; + foreach (var drawInstance in DrawInstances) + { + var geometry = drawInstance.Key; + geometry.Bind(); + + foreach (var colorEntry in drawInstance.Value) + { + ColorParameter.SetValue(colorEntry.Key.ToVector3()); + + matrices = colorEntry.Value; + count = matrices.Count; + + for (var index = 0; index < count; index++) + { + WorldViewProjectionParameter.SetValue(matrices[index]); + pass.Apply(); + geometry.Draw(); + } + } + } + } + + /// + /// Draws all Gizmos that are poly-lines. + /// + /// The pass from an effect to draw the geometry with. + private void DrawPolyLines(EffectPass pass) + { + var count = 0; + List positions; + WorldViewProjectionParameter.SetValue(Matrix.Identity); + foreach (var polyLineInstance in PolyLinesToDraw) + { + ColorParameter.SetValue(polyLineInstance.Key.ToVector3()); + + positions = polyLineInstance.Value; + count = positions.Count; + for (var index = 0; index < count; index++) + { + pass.Apply(); + PolyLine.Draw(positions[index]); + } + } + } + + /// + /// Clears all the draw instances, so we don't draw the same as the past frame. + /// + private void CleanDrawInstances() + { + PolyLinesToDraw.Clear(); + + DrawInstances[LineSegment].Clear(); + DrawInstances[Sphere].Clear(); + DrawInstances[Cube].Clear(); + DrawInstances[Disk].Clear(); + DrawInstances[Cylinder].Clear(); + } + + /// + /// Disposes the used resources (geometries and content). + /// + public void Dispose() + { + LineSegment.Dispose(); + Sphere.Dispose(); + Cube.Dispose(); + Disk.Dispose(); + Cylinder.Dispose(); + Effect.Dispose(); + Content.Dispose(); + } + } +} \ No newline at end of file diff --git a/TGC.MonoGame.TP/Program.cs b/TGC.MonoGame.TP/Program.cs index 0f7e87520..828b10413 100644 --- a/TGC.MonoGame.TP/Program.cs +++ b/TGC.MonoGame.TP/Program.cs @@ -1,13 +1,13 @@ using System; -namespace TGC.MonoGame.TP +namespace ThunderingTanks { public static class Program { [STAThread] static void Main() { - using (var game = new TGCGame()) + using (var game = new TankGame()) game.Run(); } } diff --git a/TGC.MonoGame.TP/Properties/PublishProfiles/FolderProfile.pubxml b/TGC.MonoGame.TP/Properties/PublishProfiles/FolderProfile.pubxml new file mode 100644 index 000000000..2568e1d09 --- /dev/null +++ b/TGC.MonoGame.TP/Properties/PublishProfiles/FolderProfile.pubxml @@ -0,0 +1,15 @@ + + + + + Release + Any CPU + C:\Users\Lucas Gelabert\Desktop + FileSystem + <_TargetId>Folder + net6.0-windows + false + + \ No newline at end of file diff --git a/TGC.MonoGame.TP/SimpleTerrain.cs b/TGC.MonoGame.TP/SimpleTerrain.cs new file mode 100644 index 000000000..394986ba8 --- /dev/null +++ b/TGC.MonoGame.TP/SimpleTerrain.cs @@ -0,0 +1,227 @@ +using Microsoft.Xna.Framework; +using Microsoft.Xna.Framework.Graphics; + +namespace ThunderingTanks +{ + /// + /// Permite crear la malla de un terreno en base a una textura de Heightmap. + /// + public class SimpleTerrain + { + private readonly Texture2D colorMapTexture; + private readonly Effect Effect; + private float m_scaleXZ = 1; + private float m_scaleY = 1; + private readonly Texture2D terrainTexture; + private readonly Texture2D terrainTexture2; + private VertexBuffer vbTerrain; + + public SimpleTerrain(GraphicsDevice graphicsDevice, Texture2D heightMap, Texture2D colorMap, + Texture2D diffuseMap, Texture2D diffuseMap2, Effect effect) + { + //Shader + Effect = effect; + + // cargo el heightmap + LoadHeightmap(graphicsDevice, heightMap, 600, 150, Vector3.Zero); + // textura con el color Map + colorMapTexture = colorMap; + // diffuse maps auxiliares + terrainTexture = diffuseMap; + terrainTexture2 = diffuseMap2; + } + + /// + /// Valor de Y para cada par (X,Z) del Heightmap + /// + public int[,] HeightmapData { get; private set; } + + /// + /// Centro del terreno + /// + public Vector3 Center { get; private set; } + + /// + /// Renderiza el terreno + /// + public void Draw(Matrix world, Matrix view, Matrix projection) + { + var graphicsDevice = Effect.GraphicsDevice; + + Effect.Parameters["EnableTerrainDraw"].SetValue(true); + + Effect.Parameters["texColorMap"].SetValue(colorMapTexture); + Effect.Parameters["texDiffuseMap"].SetValue(terrainTexture); + Effect.Parameters["texDiffuseMap2"].SetValue(terrainTexture2); + Effect.Parameters["World"].SetValue(world); + Effect.Parameters["View"].SetValue(view); + Effect.Parameters["Projection"].SetValue(projection); + + graphicsDevice.SetVertexBuffer(vbTerrain); + + foreach (var pass in Effect.CurrentTechnique.Passes) + { + pass.Apply(); + graphicsDevice.DrawPrimitives(PrimitiveType.TriangleList, 0, vbTerrain.VertexCount / 3); + } + + Effect.Parameters["EnableTerrainDraw"].SetValue(false); + } + + /// + /// Crea la malla de un terreno en base a un Heightmap + /// + /// Imagen de Heightmap + /// Escala para los ejes X y Z + /// Escala para el eje Y + /// Centro de la malla del terreno + public void LoadHeightmap(GraphicsDevice graphicsDevice, Texture2D heightmap, float scaleXZ, float scaleY, + Vector3 center) + { + Center = center; + + m_scaleXZ = scaleXZ; + m_scaleY = scaleY; + + float tx_scale = 1; // 50f; + + //cargar heightmap + HeightmapData = LoadHeightMap(heightmap); + var width = HeightmapData.GetLength(0); + var length = HeightmapData.GetLength(1); + + float min_h = 256; + float max_h = 0; + for (var i = 0; i < width; i++) + for (var j = 0; j < length; j++) + { + //HeightmapData[i, j] = 256 - HeightmapData[i, j]; + if (HeightmapData[i, j] > max_h) + max_h = HeightmapData[i, j]; + if (HeightmapData[i, j] < min_h) + min_h = HeightmapData[i, j]; + } + + //Cargar vertices + var totalVertices = 2 * 3 * (HeightmapData.GetLength(0) - 1) * (HeightmapData.GetLength(1) - 1); + var dataIdx = 0; + var data = new VertexPositionNormalTexture[totalVertices]; + + center.X = center.X * scaleXZ - width / 2f * scaleXZ; + center.Y = center.Y * scaleY; + center.Z = center.Z * scaleXZ - length / 2f * scaleXZ; + + var N = new Vector3[width, length]; + for (var i = 0; i < width - 1; i++) + for (var j = 0; j < length - 1; j++) + { + var v1 = new Vector3(center.X + i * scaleXZ, center.Y + HeightmapData[i, j] * scaleY, + center.Z + j * scaleXZ); + var v2 = new Vector3(center.X + i * scaleXZ, center.Y + HeightmapData[i, j + 1] * scaleY, + center.Z + (j + 1) * scaleXZ); + var v3 = new Vector3(center.X + (i + 1) * scaleXZ, center.Y + HeightmapData[i + 1, j] * scaleY, + center.Z + j * scaleXZ); + N[i, j] = Vector3.Normalize(Vector3.Cross(v2 - v1, v3 - v1)); + } + + for (var i = 0; i < width - 1; i++) + for (var j = 0; j < length - 1; j++) + { + //Vertices + var v1 = new Vector3(center.X + i * scaleXZ, center.Y + HeightmapData[i, j] * scaleY, + center.Z + j * scaleXZ); + var v2 = new Vector3(center.X + i * scaleXZ, center.Y + HeightmapData[i, j + 1] * scaleY, + center.Z + (j + 1) * scaleXZ); + var v3 = new Vector3(center.X + (i + 1) * scaleXZ, center.Y + HeightmapData[i + 1, j] * scaleY, + center.Z + j * scaleXZ); + var v4 = new Vector3(center.X + (i + 1) * scaleXZ, center.Y + HeightmapData[i + 1, j + 1] * scaleY, + center.Z + (j + 1) * scaleXZ); + + //Coordendas de textura + var t1 = new Vector2(i / (float)width, j / (float)length) * tx_scale; + var t2 = new Vector2(i / (float)width, (j + 1) / (float)length) * tx_scale; + var t3 = new Vector2((i + 1) / (float)width, j / (float)length) * tx_scale; + var t4 = new Vector2((i + 1) / (float)width, (j + 1) / (float)length) * tx_scale; + + //Cargar triangulo 1 + data[dataIdx] = new VertexPositionNormalTexture(v1, N[i, j], t1); + data[dataIdx + 1] = new VertexPositionNormalTexture(v2, N[i, j + 1], t2); + data[dataIdx + 2] = new VertexPositionNormalTexture(v4, N[i + 1, j + 1], t4); + + //Cargar triangulo 2 + data[dataIdx + 3] = new VertexPositionNormalTexture(v1, N[i, j], t1); + data[dataIdx + 4] = new VertexPositionNormalTexture(v4, N[i + 1, j + 1], t4); + data[dataIdx + 5] = new VertexPositionNormalTexture(v3, N[i + 1, j], t3); + + dataIdx += 6; + } + + //Crear vertexBuffer + vbTerrain = new VertexBuffer(graphicsDevice, VertexPositionNormalTexture.VertexDeclaration, totalVertices, + BufferUsage.WriteOnly); + vbTerrain.SetData(data); + } + + /// + /// Carga los valores del Heightmap en una matriz + /// + protected int[,] LoadHeightMap(Texture2D texture) + { + var width = texture.Width; + var height = texture.Height; + var rawData = new Color[width * height]; + texture.GetData(rawData); + var heightmap = new int[width, height]; + + for (var i = 0; i < width; i++) + for (var j = 0; j < height; j++) + { + //(j, i) invertido para primero barrer filas y despues columnas + var pixel = rawData[j * texture.Width + i]; + var intensity = pixel.R * 0.299f + pixel.G * 0.587f + pixel.B * 0.114f; + heightmap[i, j] = (int)intensity; + } + + return heightmap; + } + + public float Height(float x, float z) + { + var width = HeightmapData.GetLength(0); + var length = HeightmapData.GetLength(1); + + var pos_i = x / m_scaleXZ + width / 2.0f; + var pos_j = z / m_scaleXZ + length / 2.0f; + var pi = (int)pos_i; + var fracc_i = pos_i - pi; + var pj = (int)pos_j; + var fracc_j = pos_j - pj; + + if (pi < 0) + pi = 0; + else if (pi >= width) + pi = width - 1; + + if (pj < 0) + pj = 0; + else if (pj >= length) + pj = length - 1; + + var pi1 = pi + 1; + var pj1 = pj + 1; + if (pi1 >= width) + pi1 = width - 1; + if (pj1 >= length) + pj1 = length - 1; + + // 2x2 percent closest filtering usual: + var H0 = HeightmapData[pi, pj]; + var H1 = HeightmapData[pi1, pj]; + var H2 = HeightmapData[pi, pj1]; + var H3 = HeightmapData[pi1, pj1]; + var H = (H0 * (1 - fracc_i) + H1 * fracc_i) * (1 - fracc_j) + (H2 * (1 - fracc_i) + H3 * fracc_i) * fracc_j; + + return H * m_scaleY; + } + } +} \ No newline at end of file diff --git a/TGC.MonoGame.TP/TGCGame.cs b/TGC.MonoGame.TP/TGCGame.cs deleted file mode 100644 index 6a06032dc..000000000 --- a/TGC.MonoGame.TP/TGCGame.cs +++ /dev/null @@ -1,161 +0,0 @@ -using System; -using Microsoft.Xna.Framework; -using Microsoft.Xna.Framework.Graphics; -using Microsoft.Xna.Framework.Input; - -namespace TGC.MonoGame.TP -{ - /// - /// Esta es la clase principal del juego. - /// Inicialmente puede ser renombrado o copiado para hacer mas ejemplos chicos, en el caso de copiar para que se - /// ejecute el nuevo ejemplo deben cambiar la clase que ejecuta Program linea 10. - /// - public class TGCGame : Game - { - public const string ContentFolder3D = "Models/"; - public const string ContentFolderEffects = "Effects/"; - public const string ContentFolderMusic = "Music/"; - public const string ContentFolderSounds = "Sounds/"; - public const string ContentFolderSpriteFonts = "SpriteFonts/"; - public const string ContentFolderTextures = "Textures/"; - - /// - /// Constructor del juego. - /// - public TGCGame() - { - // Maneja la configuracion y la administracion del dispositivo grafico. - Graphics = new GraphicsDeviceManager(this); - - Graphics.PreferredBackBufferWidth = GraphicsAdapter.DefaultAdapter.CurrentDisplayMode.Width - 100; - Graphics.PreferredBackBufferHeight = GraphicsAdapter.DefaultAdapter.CurrentDisplayMode.Height - 100; - - // Para que el juego sea pantalla completa se puede usar Graphics IsFullScreen. - // Carpeta raiz donde va a estar toda la Media. - Content.RootDirectory = "Content"; - // Hace que el mouse sea visible. - IsMouseVisible = true; - } - - private GraphicsDeviceManager Graphics { get; } - private SpriteBatch SpriteBatch { get; set; } - private Model Model { get; set; } - private Effect Effect { get; set; } - private float Rotation { get; set; } - private Matrix World { get; set; } - private Matrix View { get; set; } - private Matrix Projection { get; set; } - - /// - /// Se llama una sola vez, al principio cuando se ejecuta el ejemplo. - /// Escribir aqui el codigo de inicializacion: el procesamiento que podemos pre calcular para nuestro juego. - /// - protected override void Initialize() - { - // La logica de inicializacion que no depende del contenido se recomienda poner en este metodo. - - // Apago el backface culling. - // Esto se hace por un problema en el diseno del modelo del logo de la materia. - // Una vez que empiecen su juego, esto no es mas necesario y lo pueden sacar. - var rasterizerState = new RasterizerState(); - rasterizerState.CullMode = CullMode.None; - GraphicsDevice.RasterizerState = rasterizerState; - // Seria hasta aca. - - // Configuramos nuestras matrices de la escena. - World = Matrix.Identity; - View = Matrix.CreateLookAt(Vector3.UnitZ * 150, Vector3.Zero, Vector3.Up); - Projection = - Matrix.CreatePerspectiveFieldOfView(MathHelper.PiOver4, GraphicsDevice.Viewport.AspectRatio, 1, 250); - - base.Initialize(); - } - - /// - /// Se llama una sola vez, al principio cuando se ejecuta el ejemplo, despues de Initialize. - /// Escribir aqui el codigo de inicializacion: cargar modelos, texturas, estructuras de optimizacion, el procesamiento - /// que podemos pre calcular para nuestro juego. - /// - protected override void LoadContent() - { - // Aca es donde deberiamos cargar todos los contenido necesarios antes de iniciar el juego. - SpriteBatch = new SpriteBatch(GraphicsDevice); - - // Cargo el modelo del logo. - Model = Content.Load(ContentFolder3D + "tgc-logo/tgc-logo"); - - // Cargo un efecto basico propio declarado en el Content pipeline. - // En el juego no pueden usar BasicEffect de MG, deben usar siempre efectos propios. - Effect = Content.Load(ContentFolderEffects + "BasicShader"); - - // Asigno el efecto que cargue a cada parte del mesh. - // Un modelo puede tener mas de 1 mesh internamente. - foreach (var mesh in Model.Meshes) - { - // Un mesh puede tener mas de 1 mesh part (cada 1 puede tener su propio efecto). - foreach (var meshPart in mesh.MeshParts) - { - meshPart.Effect = Effect; - } - } - - base.LoadContent(); - } - - /// - /// Se llama en cada frame. - /// Se debe escribir toda la logica de computo del modelo, asi como tambien verificar entradas del usuario y reacciones - /// ante ellas. - /// - protected override void Update(GameTime gameTime) - { - // Aca deberiamos poner toda la logica de actualizacion del juego. - - // Capturar Input teclado - if (Keyboard.GetState().IsKeyDown(Keys.Escape)) - { - //Salgo del juego. - Exit(); - } - - // Basado en el tiempo que paso se va generando una rotacion. - Rotation += Convert.ToSingle(gameTime.ElapsedGameTime.TotalSeconds); - - World = Matrix.CreateRotationY(Rotation); - - base.Update(gameTime); - } - - /// - /// Se llama cada vez que hay que refrescar la pantalla. - /// Escribir aqui el codigo referido al renderizado. - /// - protected override void Draw(GameTime gameTime) - { - // Aca deberiamos poner toda la logia de renderizado del juego. - GraphicsDevice.Clear(Color.Black); - - // Para dibujar le modelo necesitamos pasarle informacion que el efecto esta esperando. - Effect.Parameters["View"].SetValue(View); - Effect.Parameters["Projection"].SetValue(Projection); - Effect.Parameters["DiffuseColor"].SetValue(Color.DarkBlue.ToVector3()); - - foreach (var mesh in Model.Meshes) - { - Effect.Parameters["World"].SetValue(mesh.ParentBone.Transform * World); - mesh.Draw(); - } - } - - /// - /// Libero los recursos que se cargaron en el juego. - /// - protected override void UnloadContent() - { - // Libero los recursos. - Content.Unload(); - - base.UnloadContent(); - } - } -} \ No newline at end of file diff --git a/TGC.MonoGame.TP/TankGame.cs b/TGC.MonoGame.TP/TankGame.cs new file mode 100644 index 000000000..85e949f21 --- /dev/null +++ b/TGC.MonoGame.TP/TankGame.cs @@ -0,0 +1,1058 @@ +using Microsoft.Xna.Framework; +using Microsoft.Xna.Framework.Audio; +using Microsoft.Xna.Framework.Graphics; +using Microsoft.Xna.Framework.Input; +using System; +using System.Collections.Generic; +using MonoGame.Framework; +using ThunderingTanks.Cameras; +using ThunderingTanks.Collisions; +using ThunderingTanks.Geometries; +using ThunderingTanks.Gizmos; +using ThunderingTanks.Objects; +using ThunderingTanks.Objects.Props; +using ThunderingTanks.Objects.Tanks; +using System.DirectoryServices; + +namespace ThunderingTanks +{ + public class TankGame : Game + { + #region Content + public const string ContentFolder3D = "Models/"; + public const string ContentFolderEffects = "Effects/"; + public const string ContentFolderTextures = "Textures/"; + public const string ContentFolderFonts = "Fonts/"; + public const string ContentFolderMusic = "Music/"; + public const string ContentFolderAudio = "Audio/"; + #endregion + + #region Graphics + private GraphicsDeviceManager Graphics { get; } + + public float screenHeight; + public float screenWidth; + private Point screenCenter; + + Viewport viewport; + + public Effect BasicShader { get; private set; } + + public Effect TextureMerge { get; private set; } + + public Effect Shadows { get; private set; } + + public FullScreenQuad FSQ { get; private set; } + + public RenderTarget2D SceneRenderTarget { get; private set; } + + public RenderTarget2D ShadowRenderTarget { get; private set; } + + private const int ShadowMapSize = 2048; + + private readonly float LightCameraFarPlaneDistance = 3000f; + private readonly float TargetCameraFarPlaneDistance = 50000f; + + private readonly float LightCameraNearPlaneDistance = 5f; + private readonly float TargetCameraClosePlaneDistance = 0.1f; + + public SpriteBatch spriteBatch { get; set; } + + ParticleSystem particleSystem; + + public FrameCounter FrameCounter { get; set; } + #endregion + + #region State + public KeyboardState keyboardState; + public MouseState MouseState; + public MouseState PreviousMouseState; + #endregion + + #region Camera + private readonly Vector3 _cameraInitialPosition = new(0, 6000, 0); + + private TargetCamera _targetCamera; + private StaticCamera _lightCamera; + private Vector3 lightPosition; + private StaticCamera _staticCamera; + + private FreeCamera _freeCamera; + + private BoundingFrustum _cameraFrustum; + + public bool freeCameraIsActivated = false; + private bool GTrigger = true; + + #endregion + + #region Objects + + private Roca roca; + + private AntiTanque antitanque; + + private Trees arbol; + + private DestroyedHouse casa; + + private Molino molino; + + private Grass Grass { get; set; } + private List GrassPosition { get; set; } + + public int GrassCant = 300; + + + private GermanSoldier GermanSoldier { get; set; } + + private Shack LittleShack { get; set; } + + + public List Projectiles = new(); + + private List Rocas = new(); + private readonly int CantidadRocas = 40; + + private List Arboles = new(); + private readonly int CantidadArboles = 80; + private List AntiTanques = new List(); + private List gameObjects = new(); + + #endregion + + #region Menu + private Menu _menu; + private HUD _hud; + private bool _juegoIniciado = false; + #endregion + + #region Gizmos + + private Gizmoss Gizmos { get; set; } + + private bool DrawGizmos = false; + private bool CTrigger = true; + + #endregion + + #region Sounds + public float MasterSound { get; set; } = 1f; + public AudioEngine AudioEngine { get; set; } + public AudioEmitter AudioEmitter { get; set; } + private SoundEffect movingTankSoundEffect { get; set; } + private SoundEffect shootSoundEffect { get; set; } + private SoundEffectInstance movingTankSound { get; set; } + private SoundEffectInstance _shootSound { get; set; } + private SoundEffectInstance _shootSoundPlayer { get; set; } + #endregion + + #region Tanks + private Tank Panzer { get; set; } + + private EnemyTank enemyTank; + private List EnemyTanks = new(); + private List EliminatedEnemyTanks = new(); + + public float TanksEliminados; + public float Oleada; + public float OleadaAnterior; + public float Puntos; + private float tiempoTranscurrido = 0f; + private bool mostrandoMensaje = false; + + #endregion + + #region MapScene + private MapScene Map { get; set; } + public Vector2 MapLimit { get; set; } + private SkyBox SkyBox { get; set; } + private Matrix LightBoxWorld { get; set; } = Matrix.Identity; + private CubePrimitive lightBox; + + public Random randomSeed = new Random(47); + #endregion + + public bool StartGame { get; set; } = false; + + Vector3 ambientColorValue = new(0.7f, 0.7f, 0.7f); // Color ambiental (generalmente menos afectado por la dirección de la luz) + Vector3 diffuseColorValue = new(0.6f, 0.6f, 0.6f); // Color difuso (más brillante en la dirección de la luz) + Vector3 specularColorValue = new(0.5f, 0.5f, 0.5f); // Color especular (más brillante en la dirección de la luz) + readonly float KAmbientValue = 0.8f; // Factor de ambiental + readonly float KDiffuseValue = 0.8f; // Factor difuso + readonly float KSpecularValue = 0.5f; // Factor especular + readonly float shininessValue = 20.0f; // Brillo especular (puede ajustarse según sea necesario) + + private readonly int CantidadTanquesEnemigos = 0; + + + // ------------ GAME ------------ // + + public TankGame() + { + Graphics = new GraphicsDeviceManager(this); + Content.RootDirectory = "Content"; + IsMouseVisible = true; + Gizmos = new Gizmoss(); + } + + protected override void Initialize() + { + #region Graphics + var rasterizerState = new RasterizerState(); + rasterizerState.CullMode = CullMode.CullCounterClockwiseFace; + rasterizerState.FillMode = FillMode.Solid; + rasterizerState.MultiSampleAntiAlias = true; + + GraphicsDevice.RasterizerState = rasterizerState; + GraphicsDevice.BlendState = BlendState.AlphaBlend; + + Graphics.PreferredBackBufferWidth = GraphicsAdapter.DefaultAdapter.CurrentDisplayMode.Width; + Graphics.PreferredBackBufferHeight = GraphicsAdapter.DefaultAdapter.CurrentDisplayMode.Height; + Graphics.GraphicsProfile = GraphicsProfile.HiDef; + + viewport = GraphicsDevice.Viewport; + Graphics.IsFullScreen = true; + IsMouseVisible = false; + + Graphics.ApplyChanges(); + #endregion + + screenHeight = GraphicsDevice.Viewport.Height; + screenWidth = GraphicsDevice.Viewport.Width; + + screenCenter = new Point((int)Math.Round(screenWidth / 2.0), (int)Math.Round(screenHeight / 2)); + keyboardState = new KeyboardState(); + MouseState = new MouseState(); + PreviousMouseState = new MouseState(); + MapLimit = new Vector2(20000f, 20000f); + FrameCounter = new FrameCounter(); + Rocas = new List(CantidadRocas); + Arboles = new List(CantidadArboles); + antitanque = new AntiTanque(); + molino = new Molino(Matrix.CreateTranslation(new(randomSeed.Next((int)-MapLimit.X, (int)MapLimit.X), 0, randomSeed.Next((int)-MapLimit.Y, (int)MapLimit.Y)))); + casa = new DestroyedHouse(); + LittleShack = new Shack(); + Grass = new Grass(); + GermanSoldier = new GermanSoldier(); + Panzer = new Tank() + { + TankVelocity = 1000f, + TankRotation = 20f, + FireRate = 5f, + NumberOfProyectiles = 3 + }; + lightBox = new CubePrimitive(GraphicsDevice, 500, Color.Transparent); + _menu = new Menu(Content); + _hud = new HUD(screenWidth, screenHeight); + SkyBox = new SkyBox(25000); + Map = new MapScene(Content, GraphicsDevice); + spriteBatch = new SpriteBatch(GraphicsDevice); + _targetCamera = new TargetCamera(GraphicsDevice.Viewport.AspectRatio, _cameraInitialPosition, Panzer.PanzerMatrix.Forward, TargetCameraClosePlaneDistance, TargetCameraFarPlaneDistance); + _staticCamera = new StaticCamera(GraphicsDevice.Viewport.AspectRatio, new Vector3(400, 200, 1300), Vector3.Forward, Vector3.Up); + _freeCamera = new FreeCamera(GraphicsDevice.Viewport.AspectRatio, _cameraInitialPosition, screenCenter); + _lightCamera = new StaticCamera(1f, lightPosition, Vector3.Normalize(Vector3.Zero - lightPosition), Vector3.Up); + _cameraFrustum = new BoundingFrustum(_targetCamera.View * _targetCamera.Projection); + SceneRenderTarget = new RenderTarget2D(GraphicsDevice, GraphicsDevice.Viewport.Width, GraphicsDevice.Viewport.Height, false, SurfaceFormat.Color, DepthFormat.Depth24, 0, RenderTargetUsage.DiscardContents); + ShadowRenderTarget = new RenderTarget2D(GraphicsDevice, ShadowMapSize, ShadowMapSize, false, SurfaceFormat.Single, DepthFormat.Depth24, 0, RenderTargetUsage.PlatformContents); + FSQ = new FullScreenQuad(GraphicsDevice); + particleSystem = new ParticleSystem(GraphicsDevice); + + _lightCamera.BuildProjection(1f, LightCameraNearPlaneDistance, LightCameraFarPlaneDistance, MathHelper.PiOver2); + + AgregarRocas(CantidadRocas); + AgregarArboles(CantidadArboles); + AgregarTanquesEnemigos(CantidadTanquesEnemigos); + AgregarAntitanques(); + + GermanSoldier.Initialize(); + Panzer.SensitivityFactor = 0.45f; + casa.Position = new Vector3(-3300f, -700f, 7000f); + LittleShack.SpawnPosition(new Vector3(randomSeed.Next((int)-MapLimit.X, (int)MapLimit.X), 0f, randomSeed.Next((int)-MapLimit.Y, (int)MapLimit.Y))); + + TanksEliminados = 0; + Oleada = 1; + OleadaAnterior = 1; + Puntos = 0; + + base.Initialize(); + } + + protected override void LoadContent() + { + + BasicShader = Content.Load(ContentFolderEffects + "BasicShader"); + BasicShader.CurrentTechnique = BasicShader.Techniques["Impact"]; + TextureMerge = Content.Load(ContentFolderEffects + "TextureMerge"); + Shadows = Content.Load(ContentFolderEffects + "Shadows"); + + shootSoundEffect = Content.Load(ContentFolderMusic + "shootSound"); + movingTankSoundEffect = Content.Load(ContentFolderMusic + "movingTank"); + movingTankSound = movingTankSoundEffect.CreateInstance(); + _shootSound = shootSoundEffect.CreateInstance(); + _shootSoundPlayer = shootSoundEffect.CreateInstance(); + + Panzer.LoadContent(Content, BasicShader); + molino.LoadContent(Content, BasicShader); + antitanque.LoadContent(Content, BasicShader); + casa.LoadContent(Content, BasicShader); + Grass.LoadContent(Content, BasicShader); + GermanSoldier.LoadContent(Content, BasicShader); + LittleShack.LoadContent(Content, BasicShader); + _menu.LoadContent(Content); + _hud.LoadContent(Content); + SkyBox.LoadContent(Content); + Gizmos.LoadContent(GraphicsDevice, Content); + for (int i = 0; i < CantidadRocas; i++) + { + roca = Rocas[i]; + roca.LoadContent(Content, BasicShader, Map.terrain); + } + for (int i = 0; i < CantidadArboles; i++) + { + arbol = Arboles[i]; + arbol.LoadList(Content, BasicShader, Map.terrain); + } + for (int i = 0; i < CantidadTanquesEnemigos; i++) + { + enemyTank = EnemyTanks[i]; + enemyTank.LoadContent(Content, GraphicsDevice); + } + + GrassPosition = LoadGrassPositions(GrassCant); + GermanSoldier.SpawnPosition(new Vector3(0, 0, 300)); + + Panzer.MovingTankSound = movingTankSound; + + base.LoadContent(); + } + + protected override void Update(GameTime gameTime) + { + var time = Convert.ToSingle(gameTime.ElapsedGameTime.TotalSeconds); + var timeForParticles = Convert.ToSingle(gameTime.ElapsedGameTime.TotalSeconds); + + var elapsedTime = Convert.ToSingle(gameTime.TotalGameTime.TotalSeconds); + _hud.elapsedTime = elapsedTime; + _hud.Oleada = Oleada; + + UpdateOleada(time); + + if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed || Keyboard.GetState().IsKeyDown(Keys.Escape)) + Exit(); + + BasicShader.Parameters["diffuseColor"].SetValue(diffuseColorValue); + BasicShader.Parameters["ambientColor"].SetValue(ambientColorValue); + BasicShader.Parameters["specularColor"].SetValue(specularColorValue); + BasicShader.Parameters["KAmbient"].SetValue(KAmbientValue); + BasicShader.Parameters["KDiffuse"].SetValue(KDiffuseValue); + BasicShader.Parameters["KSpecular"].SetValue(KSpecularValue); + BasicShader.Parameters["shininess"].SetValue(shininessValue); + BasicShader.Parameters["lightPosition"].SetValue(lightPosition); + BasicShader.Parameters["eyePosition"].SetValue(_targetCamera.Position); + + #region Volume + + PreviousMouseState = MouseState; + MouseState = Mouse.GetState(); + + int currentScrollValue = MouseState.ScrollWheelValue; + int previousScrollValue = PreviousMouseState.ScrollWheelValue; + + int scrollDifference = currentScrollValue - previousScrollValue; + + if (scrollDifference > 0) + { + MasterSound = Math.Min(1, MasterSound + 0.05f); + } + else if (scrollDifference < 0) + { + MasterSound = Math.Max(0, MasterSound - 0.05f); + } + + _menu.MasterSound = MasterSound; + _shootSound.Volume = MasterSound; + movingTankSound.Volume = MasterSound; + + #endregion + + if (!_juegoIniciado || Panzer.isDestroyed) + { + lightPosition = new Vector3(150, 500, 150); + LightBoxWorld = Matrix.CreateTranslation(lightPosition); + + _lightCamera.Position = lightPosition; + _lightCamera.BuildView(); + + Panzer.Position = new Vector3(10, 0, 0); + Panzer.isDestroyed = false; + + Panzer.PanzerMatrix = Matrix.CreateRotationY(MathHelper.ToRadians(-10)); + Panzer.TurretMatrix = Matrix.CreateRotationY(MathHelper.ToRadians(6)); + Panzer.CannonMatrix = Matrix.CreateRotationY(MathHelper.ToRadians(6)); + + _menu.Update(ref _juegoIniciado, gameTime); + + keyboardState = Keyboard.GetState(); + } + + else + { + lightPosition = new Vector3(20000, 5000, 0); + LightBoxWorld = Matrix.CreateTranslation(lightPosition); + _lightCamera.Position = lightPosition; + _lightCamera.BuildView(); + + if (!StartGame) + { + Panzer.Position = new Vector3(-5000, 0, -11000); + StartGame = true; + } + + keyboardState = Keyboard.GetState(); + + _hud.Update(Panzer, ref viewport, Puntos); + + #region GodMode&DrawGizmos + + if (keyboardState.IsKeyDown(Keys.G) && GTrigger) + { + GTrigger = false; + freeCameraIsActivated = !freeCameraIsActivated; + } + + if (keyboardState.IsKeyUp(Keys.G)) + GTrigger = true; + + if (keyboardState.IsKeyDown(Keys.C) && CTrigger) + { + CTrigger = false; + DrawGizmos = !DrawGizmos; + } + + if (keyboardState.IsKeyUp(Keys.C)) + CTrigger = true; + + #endregion + + var lastMatrix = Panzer.PanzerMatrix; + var turretPosition = Panzer.TurretMatrix; + var cannonPosition = Panzer.CannonMatrix; + var position = Panzer.Position; + var lastRotation = Panzer.Rotation; + + if (MouseState.LeftButton == ButtonState.Pressed) + { + Projectile projectile = Panzer.Shoot(); + + if (projectile != null) + { + projectile.LoadContent(Content, BasicShader); + Projectiles.Add(projectile); + _shootSoundPlayer.Play(); + } + } + + _hud.TankPosition = Panzer.Position; + + Panzer.Update(gameTime, keyboardState, Map.terrain); + + Panzer.isColliding = false; + _hud.TankIsColliding = false; + + if (CheckCollisions()) + { + _hud.TankIsColliding = true; + Panzer.isColliding = true; + + Panzer.PanzerMatrix = lastMatrix; + Panzer.TurretMatrix = turretPosition; + Panzer.CannonMatrix = cannonPosition; + Panzer.Position = position; + Panzer.Rotation = lastRotation; + Panzer.Update(gameTime, keyboardState, Map.terrain); + } + + screenHeight = GraphicsDevice.Viewport.Height; + screenWidth = GraphicsDevice.Viewport.Width; + Mouse.SetPosition((int)screenWidth / 2, (int)screenHeight / 2); + + foreach (var enemyTank in EnemyTanks) + { + enemyTank.Update(gameTime, Panzer.Position, Map.terrain, GraphicsDevice, _targetCamera); + enemyTank.lifeSpan += time; + + if (enemyTank.lifeSpan >= enemyTank.shootInterval) + { + Projectile projectile = enemyTank.Shoot(); + if (projectile != null) + { + Projectiles.Add(projectile); + projectile.LoadContent(Content, BasicShader); + _shootSound.Play(); + _shootSound.Volume = 1.0f; + } + enemyTank.lifeSpan = 0f; + } + } + + foreach (var enemyTank in EliminatedEnemyTanks) + { + enemyTank.Update(gameTime, Panzer.Position, Map.terrain, GraphicsDevice, _targetCamera); + enemyTank.StopEnemy(); + } + + UpdateProjectiles(gameTime); + + _hud.TimeSinceLastShot = Panzer.TimeSinceLastShot; + + _targetCamera.Update(Panzer.CameraPosition, Panzer.GunRotation + MathHelper.ToRadians(180)); + _freeCamera.Update(gameTime); + } + + base.Update(gameTime); + } + + protected override void Draw(GameTime gameTime) + { + + float time = (float)(gameTime.ElapsedGameTime.TotalSeconds); + FrameCounter.Update(time); + _hud.FPS = FrameCounter.AverageFramesPerSecond; + + if (!_juegoIniciado || Panzer.isDestroyed) + { + Panzer.isDestroyed = false; + + #region MENU + + GraphicsDevice.DepthStencilState = DepthStencilState.Default; + GraphicsDevice.BlendState = BlendState.AlphaBlend; + + GraphicsDevice.Clear(ClearOptions.Target | ClearOptions.DepthBuffer, Color.Black, 1f, 0); + + Camera camara = _staticCamera; + Panzer.Draw(camara.View, camara.Projection, GraphicsDevice); + + + spriteBatch.Begin(); + _menu.Draw(spriteBatch); + spriteBatch.End(); + Panzer.CurrentLife = Panzer.MaxLife; + #endregion + + } + else + { + #region Pass 1 + + GraphicsDevice.DepthStencilState = DepthStencilState.Default; + + GraphicsDevice.SetRenderTarget(SceneRenderTarget); + + TextureMerge.CurrentTechnique = TextureMerge.Techniques["Merge"]; + + GraphicsDevice.BlendState = BlendState.AlphaBlend; + GraphicsDevice.Clear(ClearOptions.Target | ClearOptions.DepthBuffer, Color.CornflowerBlue, 1f, 0); + + Camera camera; + + if (freeCameraIsActivated) + camera = _freeCamera; + else + camera = _targetCamera; + + DrawProjectiles(camera.View, camera.Projection); + DrawSkyBox(camera.View, camera.Projection, camera.Position); + + FrustumDraw(gameTime, camera); + + lightBox.Draw(LightBoxWorld, _targetCamera.View, _targetCamera.Projection); + Map.Draw(gameTime, camera.View, camera.Projection, GraphicsDevice); + //antitanque.Draw(gameTime, camera.View, camera.Projection, Map.terrain); + Panzer.Draw(camera.View, camera.Projection, GraphicsDevice); + Grass.Draw(GrassPosition, camera.View, camera.Projection, Map.terrain); + + Gizmos.DrawCube((casa.BoundingBox.Max + casa.BoundingBox.Min) / 2f, casa.BoundingBox.Max - casa.BoundingBox.Min, Color.Red); + Gizmos.DrawOrientedCube(Panzer.TankBox.Center, Panzer.TankBox.Orientation, Panzer.TankBox.Extents * 2, Color.Green); + Gizmos.DrawFrustum((_targetCamera.View * _targetCamera.Projection), Color.White); + + var RayOrigin = Panzer.Position + new Vector3(0f, 210f, 0f); + Ray ray = new(RayOrigin, Panzer.CannonMatrix.Backward); + Gizmos.DrawLine(RayOrigin, RayOrigin + Panzer.TurretMatrix.Backward * 10000f, Color.Blue); + + /* + foreach(var enemyTank in EnemyTanks) + { + if(ray.Intersects(enemyTank.TankBox) != null) + Gizmos.DrawLine(RayOrigin, RayOrigin + Panzer.CannonMatrix.Backward * 10000f, Color.Red); + else + Gizmos.DrawLine(RayOrigin, RayOrigin + Panzer.CannonMatrix.Backward * 10000f, Color.Blue); + + } + */ // Rayo de colision con los tanques enemigos + + _hud.RayDirection = RayOrigin + Panzer.CannonMatrix.Backward; + _hud.RayPosition = RayOrigin; + + if (DrawGizmos) + { + _hud.DrawDebug = true; + Gizmos.UpdateViewProjection(camera.View, camera.Projection); + Gizmos.Draw(); + } + else + { + _hud.DrawDebug = false; + } + + #endregion + + #region Pass 2 + + GraphicsDevice.DepthStencilState = DepthStencilState.None; + GraphicsDevice.SetRenderTarget(null); + + TextureMerge.Parameters["baseTexture"].SetValue(SceneRenderTarget); + FSQ.Draw(TextureMerge); + + spriteBatch.Begin(); + + _hud.Draw(spriteBatch); + + spriteBatch.End(); + + #endregion + } + + base.Draw(gameTime); + } + + protected override void UnloadContent() + { + Content.Unload(); + base.UnloadContent(); + } + + // ------------ FUNCTIONS ------------ // + + /// + /// Dibuja el SkyBox en el juego + /// + /// Matriz de Vista + /// Matriz de Proyeccion + /// Posicion del Jugador + private void DrawSkyBox(Matrix view, Matrix projection, Vector3 position) + { + var originalRasterizerState = GraphicsDevice.RasterizerState; + var rasterizerState = new RasterizerState(); + + rasterizerState.CullMode = CullMode.None; + + GraphicsDevice.RasterizerState = rasterizerState; + + SkyBox.Draw(view, projection, position); + + GraphicsDevice.RasterizerState = originalRasterizerState; + } + + /// + /// Carga la posicion de los los objetos Antitanque en el borde del mapa + /// + private void AgregarAntitanques() + { + float DistanceToEdge = 40f; + + for (float i = 0; i < 80f; i += 1f) + { + Vector3 Corner1 = new Vector3(DistanceToEdge, 0, DistanceToEdge - i); + Vector3 Corner2 = new Vector3((-1 * DistanceToEdge) + i, 0, DistanceToEdge); + Vector3 Corner3 = new Vector3(DistanceToEdge - i, 0, (-1 * DistanceToEdge)); + Vector3 Corner4 = new Vector3((-1 * DistanceToEdge), 0, (-1 * DistanceToEdge) + i); + + antitanque.AgregarAntitanque(Corner1); + antitanque.AgregarAntitanque(Corner2); + antitanque.AgregarAntitanque(Corner3); + antitanque.AgregarAntitanque(Corner4); + } + } + + /// + /// Carga la posicion de de los objetos Rocas en posiciones aleatorias pregenerdas + /// + /// Cantidad de Rocas + private void AgregarRocas(int cantidad) + { + for (int i = 0; i < cantidad; i++) + { + Vector3 randomPosition = new Vector3( + (float)(randomSeed.NextDouble() * 40000 - 20000), // X entre -100 y 100 + 150f, // Y + (float)(randomSeed.NextDouble() * 40000 - 20000) // Z entre -100 y 100 + ); + roca = new Roca(); + { + roca.Position = randomPosition; + } + + + Rocas.Add(roca); + } + } + + /// + /// Carga la posicion de de los objetos Arboles en posiciones aleatorias pregenerdas + /// + /// Cantidad de Arboles + private void AgregarArboles(int cantidad) + { + + for (int i = 0; i < cantidad; i++) + { + Vector3 randomPosition = new Vector3( + (float)(randomSeed.NextDouble() * 40000 - 20000), // X entre -100 y 100 + 0f, // Y + (float)(randomSeed.NextDouble() * 40000 - 20000) // Z entre -100 y 100 + ); + + arbol = new Trees(); + { + arbol.SpawnPosition(randomPosition); + } + Arboles.Add(arbol); + + } + } + + /// + /// Carga la posicion de de los objetos TanquesEnemigos en posiciones pregenerdas + /// + /// + private void AgregarTanquesEnemigos(int cantidad) + { + for (int i = 0; i < cantidad; i++) + { + EnemyTank enemyTank = new EnemyTank(GraphicsDevice) + { + TankVelocity = 180f, + TankRotation = 20f, + FireRate = 5f, + Position = new Vector3(3000 * i, 0, 9000), + shootInterval = 5f + ((float)Math.Pow(2, i)), + lifeSpan = 0 + }; + EnemyTanks.Add(enemyTank); + } + } + + /// + /// Actualiza la posicion y verifica la colision de los projectiles disparados + /// + /// + public void UpdateProjectiles(GameTime gameTime) + { + for (int j = 0; j < Projectiles.Count; ++j) + { + _hud.BulletCount = Projectiles.Count; + + if (OutOfMap(Projectiles[j].PositionVector) || HitFlor(Projectiles[j].PositionVector)) + { + Projectiles.Remove(Projectiles[j]); + break; + } + + if (Panzer.TankBox.Intersects(Projectiles[j].ProjectileBox)) + { + Panzer.ReceiveDamage(ref _juegoIniciado); + + Projectiles.Remove(Projectiles[j]); + break; + } + + if (Projectiles.Count <= j || Projectiles.Count == 0) + break; + + for (int i = 0; i < Rocas.Count; ++i) + { + if (Projectiles[j].ProjectileBox.Intersects(Rocas[i].RocaBox)) + { + Projectiles.Remove(Projectiles[j]); + Rocas.Remove(Rocas[i]); + break; + } + } + + if (Projectiles.Count <= j || Projectiles.Count == 0) + break; + + for (int i = EnemyTanks.Count - 1; i >= 0; i--) + { + if (Projectiles[j].ProjectileBox.Intersects(EnemyTanks[i].TankBox)) + { + Projectiles.Remove(Projectiles[j]); + + EnemyTanks[i].life -= 5; + + if (EnemyTanks[i].life <= 0) + { + EliminatedEnemyTanks.Add(EnemyTanks[i]); + TanksEliminados++; + + EnemyTanks.RemoveAt(i); + + Puntos += (i + 1) * Oleada; + } + + if (TanksEliminados == CantidadTanquesEnemigos) + { + AgregarTanquesEnemigos(CantidadTanquesEnemigos); + + for (int k = 0; k < CantidadTanquesEnemigos; k++) + { + enemyTank = EnemyTanks[k]; + enemyTank.LoadContent(Content, GraphicsDevice); + } + + TanksEliminados = 0; + Oleada++; + + if (Oleada == 10) + { + Panzer.CurrentLife = Panzer.MaxLife; + Exit(); + } + + } + break; + } + } + + if (Projectiles.Count <= j || Projectiles.Count == 0) + break; + + Projectiles[j].Update(gameTime); + + } + } + + /// + /// Verifica si la posicion pasada por parametro se encuentra fuera del mapa + /// + /// Posicion del obejto a evaluar + /// True si esta fuera del mapa + public bool OutOfMap(Vector3 position) + { + if ( + position.X > MapLimit.X || + position.X < -MapLimit.X || + + position.Z > MapLimit.Y || + position.Z < -MapLimit.Y + ) + return true; + else + return false; + } + + /// + /// Verifica que el proyectil no colicione con el terreno + /// + /// + /// + public bool HitFlor(Vector3 position) + { + var Height = Map.terrain.Height(position.X, position.Z) - 300; // Se le resta 300 porque el terreno tiene un offset de 300 + + if (position.Y < Height) + return true; + else + return false; + } + + /// + /// Dibuja los proyectiles que fueron disparados y estan presentes en el juego + /// + /// Matriz de Vista + /// Matriz de Proyeccion + public void DrawProjectiles(Matrix view, Matrix projection) + { + foreach (Projectile projectile in Projectiles) + { + projectile.Draw(view, projection); + Gizmos.DrawCube(CollisionsClass.GetCenter(projectile.ProjectileBox), CollisionsClass.GetExtents(projectile.ProjectileBox) * 2, Color.Red); + } + } + + /// + /// Chequea si hay alguna colision entre los tanques y entre un tanques y el entorno + /// + /// True si hay colision + private bool CheckCollisions() + { + OrientedBoundingBox tankBox = Panzer.TankBox; + + Vector3 deltaY = new(2500, 4800, 200); + + foreach (var roca in Rocas) + { + if (tankBox.Intersects(roca.RocaBox)) + { + return true; + } + } + + foreach (var arbol in Arboles) + { + if (tankBox.Intersects(arbol.BoundingBox)) + { + return true; + } + } + + if (tankBox.Intersects(casa.BoundingBox)) + { + return true; + } + + foreach (var EnemyTank in EnemyTanks) + { + if (tankBox.Intersects(EnemyTank.TankBox)) + { + return true; + } + } + + foreach (var EnemyTank in EliminatedEnemyTanks) + { + if (tankBox.Intersects(EnemyTank.TankBox)) + { + return true; + } + } + + if (OutOfMap(Panzer.Position)) + { + return true; + } + + return false; + } + + /// + /// Crea posiciones aleatorias para la hierva + /// + /// Cantidad de elementos que se crearan + /// Una lista de posiciones + public List LoadGrassPositions(int Cantidad) + { + List grassPositions = new List(); + + Random random = new Random(); + for (int i = 0; i < Cantidad; i++) + { + grassPositions.Add(new Vector3(random.Next(-(int)MapLimit.X, (int)MapLimit.X), 0, random.Next(-(int)MapLimit.Y, (int)MapLimit.Y))); + } + + return grassPositions; + } + + /// + /// Actualiza los elementos cuando se cambia de oleada + /// + /// + private void UpdateOleada(float time) + { + if (Oleada != OleadaAnterior) + { + mostrandoMensaje = true; + tiempoTranscurrido = 0f; + OleadaAnterior = Oleada; + } + + if (mostrandoMensaje) + { + tiempoTranscurrido += time; + if (tiempoTranscurrido >= 3f) + { + _hud.siguienteOleada = false; + mostrandoMensaje = false; + tiempoTranscurrido = 0f; + } + else + { + _hud.siguienteOleada = true; + + for (int i = 0; i < EnemyTanks.Count; i++) + { + EnemyTanks[i].Position = new Vector3(3000 * i, 0, 9000); + } + } + } + else + { + _hud.siguienteOleada = false; + } + } + + /// + /// Dibuja los objetos que se encuentran dentro del frustum de la camara + /// + /// + public void FrustumDraw(GameTime gameTime, Camera camera) + { + Camera camara = camera; + + foreach (var roca in Rocas) + { + if (_cameraFrustum.Intersects(roca.RocaBox)) + { + roca.Draw(gameTime, camara.View, camara.Projection); + Gizmos.DrawCube((roca.RocaBox.Max + roca.RocaBox.Min) / 2f, roca.RocaBox.Max - roca.RocaBox.Min, Color.Blue); + } + } + + foreach (var arbol in Arboles) + { + if (_cameraFrustum.Intersects(arbol.BoundingBox)) + { + arbol.Draw(camara.View, camara.Projection, GraphicsDevice, Map.terrain); + Gizmos.DrawCube((arbol.MaxBox + arbol.MinBox) / 2f, arbol.MaxBox - arbol.MinBox, Color.Red); + } + } + + foreach (var enemyTank in EnemyTanks) + { + if (_cameraFrustum.Intersects(enemyTank.TankBox)) + { + enemyTank.Draw(Panzer.PanzerMatrix, camara.View, camara.Projection, GraphicsDevice); + Gizmos.DrawCube(CollisionsClass.GetCenter(enemyTank.TankBox), CollisionsClass.GetExtents(enemyTank.TankBox) * 2f, Color.Red); + } + } + + foreach (var enemyTank in EliminatedEnemyTanks) + { + if (_cameraFrustum.Intersects(enemyTank.TankBox)) + { + enemyTank.Draw(Panzer.PanzerMatrix, camara.View, camara.Projection, GraphicsDevice); + Gizmos.DrawCube(CollisionsClass.GetCenter(enemyTank.TankBox), CollisionsClass.GetExtents(enemyTank.TankBox) * 2f, Color.Red); + } + } + + if (_cameraFrustum.Intersects(LittleShack.ShackBox)) + { + LittleShack.Draw(camara.View, camara.Projection); + } + + if (_cameraFrustum.Intersects(molino.MolinoBox)) + { + molino.Draw(gameTime, camara.View, camara.Projection); + } + + if (_cameraFrustum.Intersects(casa.BoundingBox)) + { + casa.Draw(camara.View, camara.Projection); + Gizmos.DrawCube((casa.BoundingBox.Max + casa.BoundingBox.Min) / 2f, casa.BoundingBox.Max - casa.BoundingBox.Min, Color.Red); + } + } + } +} diff --git a/TGC.MonoGame.TP/TGC.MonoGame.TP.csproj b/TGC.MonoGame.TP/ThunderingTanks.csproj similarity index 56% rename from TGC.MonoGame.TP/TGC.MonoGame.TP.csproj rename to TGC.MonoGame.TP/ThunderingTanks.csproj index bb319888b..030c7f492 100644 --- a/TGC.MonoGame.TP/TGC.MonoGame.TP.csproj +++ b/TGC.MonoGame.TP/ThunderingTanks.csproj @@ -1,7 +1,7 @@ - + WinExe - net6.0 + net6.0-windows Major false false @@ -10,7 +10,13 @@ app.manifest Icon.ico True + True + + + + + @@ -26,9 +32,18 @@ - - + + + + + + + + + + + diff --git a/TGC.MonoGame.TP/app-settings.json b/TGC.MonoGame.TP/app-settings.json new file mode 100644 index 000000000..b8781bfa3 --- /dev/null +++ b/TGC.MonoGame.TP/app-settings.json @@ -0,0 +1,9 @@ +{ + "BinFolder": "bin/", + "ObjFolder": "obj/", + "ContentExtension": ".xnb", + "ContentFolder": "Content/", + "FbxExtension": ".fbx", + "FbxImporterName": "FbxImporter", + "ProcessorName": "Animation Processor" +} diff --git a/TGC.MonoGame.TP.sln b/ThunderingTanks.sln similarity index 88% rename from TGC.MonoGame.TP.sln rename to ThunderingTanks.sln index 0df7bd3bf..4bdcb0728 100644 --- a/TGC.MonoGame.TP.sln +++ b/ThunderingTanks.sln @@ -3,7 +3,7 @@ Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio Version 17 VisualStudioVersion = 17.3.32819.101 MinimumVisualStudioVersion = 10.0.40219.1 -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TGC.MonoGame.TP", "TGC.MonoGame.TP\TGC.MonoGame.TP.csproj", "{B72B2451-88F2-4BFA-A3CB-4A45C96B3F78}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ThunderingTanks", "TGC.MonoGame.TP\ThunderingTanks.csproj", "{B72B2451-88F2-4BFA-A3CB-4A45C96B3F78}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution