/// <summary>
        /// Calculates if the area is visible within a camera viewport or not
        /// </summary>
        /// <param name="area">The area</param>
        /// <param name="camera">The camera to check against</param>
        /// <returns>True if the area is visible, false if not</returns>
        public bool IsAreaVisible(Area area, CameraBase camera)
        {
            if (area.Info.IsEmpty)
            {
                return false;
            }

            // Calculate the distance from the area to the camera
            areaToCameraDistance = (area.Info.Center - camera.Position).Length();

            // Is the area within stand-on or next-to distance
            if (areaToCameraDistance < areasAlwaysVisibleWithinDistance)
            {
                return true;
            }

            // Calculate the normal from the area pointing towards the camera position
            areaLookAtNormal = (camera.Position - area.Info.Center);
            areaLookAtNormal.Normalize();

            return Vector3.Dot(camera.LookAtNormal, areaLookAtNormal) <= -0.5f;
        }
        public void UpdateCamera(CameraBase camera)
        {
            camera.Position = spatialComponent.RigidBody.Position;
            camera.Position.Y += playerComponent.CameraOffsetY;

            Matrix cameraRotation = Matrix.CreateRotationX(radian * -spatialComponent.Angle.Y) *
                                    Matrix.CreateRotationY(radian * -spatialComponent.Angle.X) *
                                    Matrix.CreateRotationZ(radian * -spatialComponent.Angle.Z);
            Vector3 upVector = Vector3.Transform(Vector3.Up, cameraRotation);
            camera.Target = camera.Position - Vector3.Transform(Vector3.Forward, cameraRotation);

            camera.View = Matrix.CreateLookAt(camera.Position, camera.Target, upVector);
        }
        public void UpdateCamera3rdPerson(CameraBase camera)
        {
            camera.Position = spatialComponent.RigidBody.Position;
            camera.Position.Y += playerComponent.CameraOffsetY;

            Vector3 thirdPersonReference = new Vector3(0, 0.4f, 4f);
            Matrix rotationMatrix = Matrix.CreateRotationY(radian * (-spatialComponent.Angle.X + 180));

            // Create a vector pointing the direction the camera is facing.
            Vector3 transformedReference = Vector3.Transform(thirdPersonReference, rotationMatrix);

            // Calculate the position the camera is looking from.
            Vector3 cameraPosition = transformedReference + spatialComponent.Position;

            camera.View = Matrix.CreateLookAt(cameraPosition, spatialComponent.Position, Vector3.Up);
        }
Example #4
0
        public void Render(GameTime gameTime, CameraBase camera)
        {
            // Clear old content
            VisibleTerrainMeshes.Clear();

            // Loop through all areas to see which ones should be rendered
            for (int i = 0; i < terrainVisibility.AreaCollection.Areas.Count; i++)
            {
                area = terrainVisibility.AreaCollection.Areas[i];

                // Skip areas not visible to the camera
                if (!terrainVisibility.IsAreaVisible(area, camera))
                {
                    continue;
                }

                // Loop through all meshes within the current area and add them to the visible groups
                foreach (KeyValuePair<TileType, TerrainMesh> meshPair in area.Model.Meshes)
                {
                    // Initialize the current mesh-group key if needed
                    if (!VisibleTerrainMeshes.ContainsKey(meshPair.Key))
                    {
                        VisibleTerrainMeshes.Add(meshPair.Key, new List<TerrainMesh>());
                    }

                    meshPair.Value.Offset.X = area.Info.Location.X * Area.Size.X;
                    meshPair.Value.Offset.Y = (area.Info.Location.Y * Area.Size.Y);
                    meshPair.Value.Offset.Z = area.Info.Location.Z * Area.Size.Z;

                    // Add the mesh to the visible groups
                    VisibleTerrainMeshes[meshPair.Key].Add(meshPair.Value);
                }
            }

            // Initiate rendering
            var device = context.Graphics.Device;
            var effect = context.Graphics.Effect as BasicEffect;
            RenderStateContext.SetRenderStates(device);

            // Loop through all visible meshes
            foreach (var meshCollection in VisibleTerrainMeshes)
            {
                // Set the current texture
                effect.Texture = context.Resources.Textures["Tile" + ((ushort)meshCollection.Key).ToString()];

                // Loop through all meshes using the current texture
                for (int i = 0; i < meshCollection.Value.Count; i++)
                {
                    mesh = meshCollection.Value[i];

                    // Skip empty meshes
                    if (mesh.VertexCount == 0 || mesh.VertexBuffer == null)
                    {
                        continue;
                    }

                    // Set the vertex and index data to be rendered
                    device.SetVertexBuffer(mesh.VertexBuffer);
                    device.Indices = mesh.IndexBuffer;

                    // Translate the mesh
                    effect.World = Matrix.CreateTranslation(mesh.Offset);

                    // Loop through all effect passes
                    for (int j = 0; j < context.Graphics.Effect.CurrentTechnique.Passes.Count; j++)
                    {
                        // Apply the current effect pass
                        context.Graphics.Effect.CurrentTechnique.Passes[j].Apply();

                        // Render the mesh
                        device.DrawIndexedPrimitives(PrimitiveType.TriangleList,
                                                     0,
                                                     0,
                                                     mesh.VertexCount,
                                                     0,
                                                     mesh.IndexCount / 3);

                    }
                }
            }
        }