Specialized Scene Node representing a camera.
        private void DrawSolidObjects(Camera camera, Matrix lightView, bool enableShadows)
        {
            _device.BlendState = BlendState.Opaque;
            foreach (var sceneNode in _solidObjects)
            {
                var worldMatrix = sceneNode.GetWorldMatrix(camera);
                if (enableShadows && sceneNode.Material.ReceiveShadow)
                {
                    _sceneEffect.ActivateLightingTechnique(true);
                    _sceneEffect.LightWorldViewProjection = worldMatrix*lightView;
                    _sceneEffect.ShadowMap = _shadowMap;
                }
                else
                {
                    _sceneEffect.ActivateLightingTechnique(false);
                }

                _sceneEffect.World = worldMatrix;
                _sceneEffect.DiffuseTexture = sceneNode.Material.DiffuseTexture;

                foreach (var pass in _sceneEffect.CurrentTechniquePasses)
                {
                    pass.Apply();
                    sceneNode.Mesh.Draw();
                }
            }
        }
Example #2
0
 public Camera CreateCamera()
 {
     var camera = new Camera(_device.Viewport);
     _allCameras.Add(camera);
     _allNodes.Add(camera);
     return camera;
 }
Example #3
0
        private void UpdateLightMatrixForDirectionalLight(Camera camera, IList<DrawableElement> shadowCasters)
        {
            var directionNormalized = Vector3.Normalize(Direction);
            var lightViewMatrix = Matrix.CreateLookAt(Vector3.Zero, Direction, Vector3.Up);

            var mergedBox = new BoundingBox();
            for (var i = 0; i < shadowCasters.Count; i++)
            {
                var drawableElement = shadowCasters[i];
                mergedBox = BoundingBox.CreateMerged(mergedBox, drawableElement.BoundingBox);
            }
            var sphere = BoundingSphere.CreateFromBoundingBox(mergedBox);

            var edges = new Vector3[8];
            edges[0] = Vector3.Transform(new Vector3(mergedBox.Min.X, mergedBox.Min.Y, mergedBox.Min.Z), lightViewMatrix);
            edges[1] = Vector3.Transform(new Vector3(mergedBox.Max.X, mergedBox.Min.Y, mergedBox.Min.Z), lightViewMatrix);
            edges[2] = Vector3.Transform(new Vector3(mergedBox.Min.X, mergedBox.Min.Y, mergedBox.Max.Z), lightViewMatrix);
            edges[3] = Vector3.Transform(new Vector3(mergedBox.Max.X, mergedBox.Min.Y, mergedBox.Max.Z), lightViewMatrix);
            edges[4] = Vector3.Transform(new Vector3(mergedBox.Min.X, mergedBox.Max.Y, mergedBox.Min.Z), lightViewMatrix);
            edges[5] = Vector3.Transform(new Vector3(mergedBox.Max.X, mergedBox.Max.Y, mergedBox.Min.Z), lightViewMatrix);
            edges[6] = Vector3.Transform(new Vector3(mergedBox.Min.X, mergedBox.Max.Y, mergedBox.Max.Z), lightViewMatrix);
            edges[7] = Vector3.Transform(new Vector3(mergedBox.Max.X, mergedBox.Max.Y, mergedBox.Max.Z), lightViewMatrix);

            var boundingBox = BoundingBox.CreateFromPoints(edges);
            var width = boundingBox.Max.X - boundingBox.Min.X;
            var height = boundingBox.Max.Y - boundingBox.Min.Y;

            var cameraPosition = sphere.Center - directionNormalized * sphere.Radius;
            var cameraPositionTarget = cameraPosition + directionNormalized;

            LightViewMatrix = Matrix.CreateLookAt(cameraPosition, cameraPositionTarget, Vector3.Up) * Matrix.CreateOrthographic(width, height, 0.1f, sphere.Radius * 2);
        }
 public CameraEntityComponent(Entity referringEntity, Skybox skybox, int cameraMask = 1) : base(referringEntity)
 {
     Camera = GameInstance.GetService<SceneRenderer>().CreateCamera(cameraMask);
     NearClipDistance = 0.1f;
     FarClipDistance = 1000.0f;
     FieldOfView = MathHelper.PiOver4;
     ClearColor = Color.CornflowerBlue;
     Camera.Skybox = skybox;
     Camera.IsActive = ReferringEntity.IsActive;
 }
        private void DrawSceneForCamera(Camera camera, Vector3 lightDirection, bool enableShadows)
        {
            _device.Clear(ClearOptions.Target | ClearOptions.DepthBuffer, Color.CornflowerBlue, 1.0f, 0);

            _sceneEffect.View = camera.ViewMatrix;
            _sceneEffect.Projection = camera.ProjectionMatrix;
            _sceneEffect.LightDirection = lightDirection;

            var lightView = BuildLightViewMatrix(lightDirection);

            DrawSolidObjects(camera, lightView, enableShadows);
            DrawTransparentObjects(camera);
        }
Example #6
0
 /// <summary>
 /// Calculates the Viewprojection Matrix of light to draw shadow map. This depends on Light Type.
 /// Directional: 
 /// 1) Create a merged bounding box of all shadow casters.
 /// 2) create enclosing sphere of boundingbox from 1) to find out to position light by taking radius as distance to ensure see all shadow casters. 
 /// 3) Transform AABB from 1) to viewspace of light and rebuild an AABB for this. this sets the size for orthogonal projection matrix.
 /// </summary>
 /// <param name="camera">needed for billboards.</param>
 /// <param name="shadowCasters">All Nodes casting a shadow for the scene.</param>
 internal void UpdateLightViewMatrixForCamera(Camera camera, IList<DrawableElement> shadowCasters)
 {
     switch (Type)
     {
         case LightType.Directional:
             UpdateLightMatrixForDirectionalLight(camera, shadowCasters);
             break;
         case LightType.Point:
             throw new NotImplementedException();
         default:
             throw new ArgumentOutOfRangeException();
     }
     
 }
        public void OnOpening()
        {
            _scene = new Scene(Game, new WindowsSceneEffect(Game.Content))
            {
                EnableShadows = false,
                LightDirection = new Vector3(0, -1, 0)
            };

            _camera = _scene.CreateCamera();
            _camera.Position = new Vector3(0.0f, 12.0f, 13.0f);
            _camera.RotateX(-MathHelper.PiOver4);
            
            var billboardSceneNode = _scene.CreateSceneNode();
            billboardSceneNode.IsBillboard = true;
            billboardSceneNode.Mesh = new Mesh(Game.GraphicsDevice, Primitives.GenerateQuadForYBillboard());
            billboardSceneNode.Material = new Material(Game.Content.Load<Texture2D>(ResourceNames.Textures.tileset1))
            {
                CastShadow = false,
                UseTransparency = true
            };
            billboardSceneNode.Position = new Vector3(-5, 0, -5);
            billboardSceneNode.Scale = new Vector3(2, 4, 1);

            for (var x = 0; x < 5; x++)
            {
                for(var z = 0; z < 5; z++)
                {
                    if (x == 0 && z == 0) continue;
                    var cloned = _scene.CloneNode(billboardSceneNode);
                    cloned.Position = new Vector3(x*2-5, 0, z * 2-5);
                }
            }

            var quads = new GeometryData[32*32];

            //2,1
            var tsize = 1.0f / 16.0f;
            for(var x = 0; x < 32; x++)
            {
                for(var z = 0; z < 32; z++)
                {
                    quads[z*32+x] = Primitives.GenerateQuadXZ(new Vector3(-16.0f + x, 0.0f, -16.0f + z), texCoordStart: new Vector2(tsize * 2.0f, tsize), texCoordScale: new Vector2(tsize, tsize));
                }
            }

            var sceneNode = _scene.CreateSceneNode();
            sceneNode.Mesh = new Mesh(Game.GraphicsDevice, Primitives.Merge(quads));
            sceneNode.Material = new Material(Game.Content.Load<Texture2D>(ResourceNames.Textures.tileset1));
        }
        private void DrawTransparentObjects(Camera camera)
        {
            _device.BlendState = BlendState.AlphaBlend;
            foreach (var sceneNode in _transparentObjects)
            {
                var worldMatrix = sceneNode.GetWorldMatrix(camera);
                if (sceneNode.IsBillboard)
                {
                    _sceneEffect.ActivateBillboardingTechnique();
                }

                _sceneEffect.World = worldMatrix;
                _sceneEffect.DiffuseTexture = sceneNode.Material.DiffuseTexture;

                foreach (var pass in _sceneEffect.CurrentTechniquePasses)
                {
                    pass.Apply();
                    sceneNode.Mesh.Draw();
                }
            }
        }
Example #9
0
        public Player(World world)
        {
            var playerEntity = world.EntitySystem.CreateEntity(true);
            var collisionSize = new Vector3(0.35f, 0.6f, 0.35f);
            var collisionOffset = new Vector3(0.0f, 0.3f, 0.0f);
            var mesh = new Mesh(GameInstance.GraphicsDevice, Primitives.GenerateQuadForYBillboard());
            var diffuseTexture = GameInstance.Content.Load<Texture2D>(ResourceNames.Textures.DefaultGuy);
            var material = new Material
            {
                DiffuseTexture = diffuseTexture,
                UseTransparency = true,
                TexcoordScale = diffuseTexture.GetTexcoordsFromPixelCoords(32, 32),
                IsUnlit = true
            };
            
            playerEntity.AddComponent(new ModelEntityComponent(playerEntity, mesh, material, true));
            playerEntity.AddComponent(new FigureMovementAnimationComponent(playerEntity, diffuseTexture));
            playerEntity.AddComponent(new CollisionEntityComponent(playerEntity, collisionSize, collisionOffset, "Player", true));
            playerEntity.Position = new Vector3(5, 0, 8);

            var cameraEntity = world.EntitySystem.CreateEntity(true);
            cameraEntity.SetParent(playerEntity);
            _controllerComponent = cameraEntity.AddComponent(new PlayerControllerComponent(cameraEntity));
            var cameraComponent = cameraEntity.AddComponent(new CameraEntityComponent(cameraEntity, new Skybox(GameInstance)
            {
                Scale = 50,
                Texture = GameInstance.Content.Load<Texture2D>(ResourceNames.Textures.skybox_texture)
            }));
            cameraComponent.FarClipDistance = 50.0f;
            Camera = cameraComponent.Camera;

            var overlayCamera = cameraEntity.AddComponent(new CameraEntityComponent(cameraEntity, null, CameraMasks.UiOverlays));
            overlayCamera.Camera.FarClipDistance = 100.0f;
            overlayCamera.Camera.ClearColor = null;
            overlayCamera.Camera.DepthClear = 1.0f;
            overlayCamera.Camera.DepthStencilState = DepthStencilState.Default;
        }
Example #10
0
 private Matrix CalculateBillboardMatrix(Camera currentCamera)
 {
     //I don't know why, but the scaling is getting negative calculating the billboard matrix.
     var bill = Matrix.CreateScale(-1,1,-1)* Matrix.CreateConstrainedBillboard(Position, currentCamera.Position, Vector3.UnitY, null, null);
     return Matrix.CreateScale(Scale) * bill;
 }
Example #11
0
 public Matrix GetWorldMatrix(Camera currentCamera)
 {
     return IsBillboard ? CalculateBillboardMatrix(currentCamera) : _world;
 }
Example #12
0
        private void DrawBoundingBox(Camera observer, Collider collider)
        {
            var scale = -collider.BoundingBox.Min + collider.BoundingBox.Max;
            var position = collider.BoundingBox.Min + scale*0.5f;
            var worldViewProjection = Matrix.CreateScale(scale)*Matrix.CreateTranslation(position)*observer.ViewMatrix*
                                      observer.ProjectionMatrix;

            _worldViewProjection.SetValue(worldViewProjection);
            _modulateColor.SetValue(collider.IsTrigger ? ColorTrigger : ColorCollider);

            _lineDrawEffect.CurrentTechnique.Passes[0].Apply();
            _boundingBoxMesh.Draw();
        }
Example #13
0
        public void Draw(Camera observer)
        {
            if (!DrawDebugShapes) return;

            GameInstance.GraphicsDevice.DepthStencilState = DepthStencilState.Default;
            GameInstance.GraphicsDevice.BlendState = BlendState.Opaque;

            var oldTechnique = _lineDrawEffect.CurrentTechnique;
            _lineDrawEffect.CurrentTechnique = _lineTechnique;

            lock (_lockObject)
            {
                for (var i = 0; i < _allTriggersAndColliders.Count; i++)
                {
                    var collider = _allTriggersAndColliders[i];
                    if (!collider.IsActive) continue;
                    switch (collider.Type)
                    {
                        case ColliderType.BoundingBox:
                            DrawBoundingBox(observer, collider);
                            break;
                    }
                }
            }

            _lineDrawEffect.CurrentTechnique = oldTechnique;
        }