Пример #1
0
            /// <summary>
            /// Creates a cube with six faces each one pointing in a different direction.
            /// </summary>
            /// <param name="device">The device.</param>
            /// <param name="size">The size.</param>
            /// <param name="toLeftHanded">if set to <c>true</c> vertices and indices will be transformed to left handed. Default is true.</param>
            /// <returns>A cube.</returns>
            public static GeometricPrimitive New(GraphicsDevice device, float size = 1.0f, bool toLeftHanded = false)
            {
                var vertices = new SolidVertex[CubeFaceCount * 4];
                var indices  = new int[CubeFaceCount * 6];

                size /= 2.0f;

                int vertexCount = 0;
                int indexCount  = 0;

                // Create each face in turn.
                for (int i = 0; i < CubeFaceCount; i++)
                {
                    Vector3 normal = faceNormals[i];

                    // Get two vectors perpendicular both to the face normal and to each other.
                    Vector3 basis = i >= 4 ? Vector3.UnitZ : Vector3.UnitY;

                    Vector3 side1 = Vector3.Cross(normal, basis);
                    Vector3 side2 = Vector3.Cross(normal, side1);

                    // Six indices (two triangles) per face.
                    int vbase = i * 4;
                    indices[indexCount++] = vbase + 2;
                    indices[indexCount++] = vbase + 1;
                    indices[indexCount++] = vbase + 0;

                    indices[indexCount++] = vbase + 3;
                    indices[indexCount++] = vbase + 2;
                    indices[indexCount++] = vbase + 0;

                    // Four vertices per face.
                    vertices[vertexCount++] = new SolidVertex((normal - side1 - side2) * size);
                    vertices[vertexCount++] = new SolidVertex((normal - side1 + side2) * size);
                    vertices[vertexCount++] = new SolidVertex((normal + side1 + side2) * size);
                    vertices[vertexCount++] = new SolidVertex((normal + side1 - side2) * size);
                }

                // Create the primitive object.
                return(new GeometricPrimitive(device, vertices, indices, toLeftHanded)
                {
                    Name = "Cube"
                });
            }
Пример #2
0
        private Buffer <SolidVertex> GetVertexBufferFromBoundingBox(BoundingBox box)
        {
            var p0 = new SolidVertex(new Vector3(box.Minimum.X, box.Minimum.Y, box.Minimum.Z));
            var p1 = new SolidVertex(new Vector3(box.Maximum.X, box.Minimum.Y, box.Minimum.Z));
            var p2 = new SolidVertex(new Vector3(box.Maximum.X, box.Minimum.Y, box.Maximum.Z));
            var p3 = new SolidVertex(new Vector3(box.Minimum.X, box.Minimum.Y, box.Maximum.Z));
            var p4 = new SolidVertex(new Vector3(box.Minimum.X, box.Maximum.Y, box.Minimum.Z));
            var p5 = new SolidVertex(new Vector3(box.Maximum.X, box.Maximum.Y, box.Minimum.Z));
            var p6 = new SolidVertex(new Vector3(box.Maximum.X, box.Maximum.Y, box.Maximum.Z));
            var p7 = new SolidVertex(new Vector3(box.Minimum.X, box.Maximum.Y, box.Maximum.Z));

            var vertices = new[]
            {
                p4, p5, p5, p1, p1, p0, p0, p4,
                p5, p6, p6, p2, p2, p1, p1, p5,
                p2, p6, p6, p7, p7, p3, p3, p2,
                p7, p4, p4, p0, p0, p3, p3, p7,
                p7, p6, p6, p5, p5, p4, p4, p7,
                p0, p1, p1, p2, p2, p3, p3, p0
            };

            return(Buffer.New(_device, vertices, BufferFlags.VertexBuffer, SharpDX.Direct3D11.ResourceUsage.Default));
        }
Пример #3
0
            /// <summary>
            /// Creates a sphere primitive.
            /// </summary>
            /// <param name="device">The device.</param>
            /// <param name="diameter">The diameter.</param>
            /// <param name="tessellation">The tessellation.</param>
            /// <param name="toLeftHanded">if set to <c>true</c> vertices and indices will be transformed to left handed. Default is true.</param>
            /// <returns>A sphere primitive.</returns>
            /// <exception cref="System.ArgumentOutOfRangeException">tessellation;Must be >= 3</exception>
            public static GeometricPrimitive New(GraphicsDevice device, float diameter = 1.0f, int tessellation = 16, bool toLeftHanded = false)
            {
                if (tessellation < 3)
                {
                    throw new ArgumentOutOfRangeException(nameof(tessellation), "Must be >= 3");
                }

                int verticalSegments   = tessellation;
                int horizontalSegments = tessellation * 2;

                var vertices = new SolidVertex[(verticalSegments + 1) * (horizontalSegments + 1)];
                var indices  = new int[verticalSegments * (horizontalSegments + 1) * 6];

                float radius = diameter / 2;

                int vertexCount = 0;

                // Create rings of vertices at progressively higher latitudes.
                for (int i = 0; i <= verticalSegments; i++)
                {
                    float v = 1.0f - (float)i / verticalSegments;

                    var latitude = (float)(i * Math.PI / verticalSegments - Math.PI / 2.0);
                    var dy       = (float)Math.Sin(latitude);
                    var dxz      = (float)Math.Cos(latitude);

                    // Create a single ring of vertices at this latitude.
                    for (int j = 0; j <= horizontalSegments; j++)
                    {
                        float u = (float)j / horizontalSegments;

                        var longitude = (float)(j * 2.0 * Math.PI / horizontalSegments);
                        var dx        = (float)Math.Sin(longitude);
                        var dz        = (float)Math.Cos(longitude);

                        dx *= dxz;
                        dz *= dxz;

                        var normal            = new Vector3(dx, dy, dz);
                        var textureCoordinate = new Vector2(u, v);

                        vertices[vertexCount++] = new SolidVertex(normal * radius);
                    }
                }

                // Fill the index buffer with triangles joining each pair of latitude rings.
                int stride = horizontalSegments + 1;

                int indexCount = 0;

                for (int i = 0; i < verticalSegments; i++)
                {
                    for (int j = 0; j <= horizontalSegments; j++)
                    {
                        int nextI = i + 1;
                        int nextJ = (j + 1) % stride;

                        indices[indexCount++] = i * stride + nextJ;
                        indices[indexCount++] = nextI * stride + j;
                        indices[indexCount++] = i * stride + j;

                        indices[indexCount++] = nextI * stride + nextJ;
                        indices[indexCount++] = nextI * stride + j;
                        indices[indexCount++] = i * stride + nextJ;
                    }
                }

                // Create the primitive object.
                return(new GeometricPrimitive(device, vertices, indices, toLeftHanded)
                {
                    Name = "Sphere"
                });
            }
Пример #4
0
            /// <summary>
            /// Creates a Plane primitive on the X/Y plane with a normal equal to -<see cref="Vector3.UnitZ" />.
            /// </summary>
            /// <param name="device">The device.</param>
            /// <param name="sizeX">The size X.</param>
            /// <param name="sizeY">The size Y.</param>
            /// <param name="tessellation">The tessellation, as the number of quads per axis.</param>
            /// <param name="uvFactor">The uv factor.</param>
            /// <param name="toLeftHanded">if set to <c>true</c> vertices and indices will be transformed to left handed. Default is true.</param>
            /// <returns>A Plane primitive.</returns>
            /// <exception cref="System.ArgumentOutOfRangeException">tessellation;tessellation must be &gt; 0</exception>
            public static GeometricPrimitive New(GraphicsDevice device, float size, int tessellation, bool toLeftHanded = false)
            {
                if (tessellation < 1)
                {
                    throw new ArgumentOutOfRangeException(nameof(tessellation), "tessellation must be > 0");
                }

                int start = (int)(-size * 1024.0f);
                int end   = (int)(size * 1024.0f);
                int step  = (int)(1024.0f / tessellation);

                var vertices = new List <SolidVertex>();
                var indices  = new List <int>();

                int lastIndex = 0;

                for (int x = start; x <= end; x += step)
                {
                    var color = Vector4.One;
                    if (x % 1024 != 0)
                    {
                        color = new Vector4(0.75f, 0.75f, 0.75f, 1.0f);
                    }
                    if (x == 0)
                    {
                        color = new Vector4(0.0f, 0.0f, 1.0f, 1.0f);
                    }

                    var v1 = new SolidVertex();
                    v1.Position = new Vector3(x, 0.0f, x == 0 ? -32768.0f : start);
                    v1.Color    = color;

                    var v2 = new SolidVertex();
                    v2.Position = new Vector3(x, 0.0f, x == 0 ? 32768.0f : end);
                    v2.Color    = color;

                    vertices.Add(v1);
                    vertices.Add(v2);

                    indices.Add(lastIndex++);
                    indices.Add(lastIndex++);
                }

                for (int z = start; z <= end; z += step)
                {
                    var color = Vector4.One;
                    if (z % 1024 != 0)
                    {
                        color = new Vector4(0.75f, 0.75f, 0.75f, 1.0f);
                    }
                    if (z == 0)
                    {
                        color = new Vector4(0.0f, 0.0f, 1.0f, 1.0f);
                    }

                    var v1 = new SolidVertex();
                    v1.Position = new Vector3(z == 0 ? -32768.0f : start, 0.0f, z);
                    v1.Color    = color;

                    var v2 = new SolidVertex();
                    v2.Position = new Vector3(z == 0 ? 32768.0f : end, 0.0f, z);
                    v2.Color    = color;

                    vertices.Add(v1);
                    vertices.Add(v2);

                    indices.Add(lastIndex++);
                    indices.Add(lastIndex++);
                }

                // Add a final Y axis line
                var vy1 = new SolidVertex();

                vy1.Position = new Vector3(0.0f, -32768.0f, 0.0f);
                vy1.Color    = new Vector4(0.0f, 0.0f, 1.0f, 1.0f);

                var vy2 = new SolidVertex();

                vy2.Position = new Vector3(0.0f, 32768.0f, 0.0f);
                vy2.Color    = new Vector4(0.0f, 0.0f, 1.0f, 1.0f);

                vertices.Add(vy1);
                vertices.Add(vy2);

                indices.Add(lastIndex++);
                indices.Add(lastIndex++);

                // Create the primitive object.
                return(new GeometricPrimitive(device, vertices.ToArray(), indices.ToArray(), toLeftHanded)
                {
                    Name = "Grid"
                });
            }
Пример #5
0
        protected override void OnDraw()
        {
            // To make sure things are in a defined state for legacy rendering...
            ((TombLib.Rendering.DirectX11.Dx11RenderingSwapChain)SwapChain).BindForce();
            ((TombLib.Rendering.DirectX11.Dx11RenderingDevice)Device).ResetState();

            _device.SetDepthStencilState(_device.DepthStencilStates.Default);
            _device.SetRasterizerState(_device.RasterizerStates.CullBack);
            _device.SetBlendState(_device.BlendStates.Opaque);

            Matrix4x4 viewProjection = Camera.GetViewProjectionMatrix(ClientSize.Width, ClientSize.Height);

            Effect solidEffect = _deviceManager.___LegacyEffects["Solid"];

            if (Static != null)
            {
                var model = _wadRenderer.GetStatic(Static);

                var effect = _deviceManager.___LegacyEffects["StaticModel"];

                var world = GizmoTransform;

                effect.Parameters["ModelViewProjection"].SetValue((world * viewProjection).ToSharpDX());
                effect.Parameters["Color"].SetValue(Vector4.One);
                effect.Parameters["Texture"].SetResource(_wadRenderer.Texture);
                effect.Parameters["TextureSampler"].SetResource(_device.SamplerStates.Default);

                for (int i = 0; i < model.Meshes.Count; i++)
                {
                    var mesh = model.Meshes[i];

                    _device.SetVertexBuffer(0, mesh.VertexBuffer);
                    _device.SetIndexBuffer(mesh.IndexBuffer, true);
                    _device.SetVertexInputLayout(VertexInputLayout.FromBuffer(0, mesh.VertexBuffer));

                    effect.Parameters["ModelViewProjection"].SetValue((world * viewProjection).ToSharpDX());
                    effect.Techniques[0].Passes[0].Apply();

                    foreach (var submesh in mesh.Submeshes)
                    {
                        _device.Draw(PrimitiveType.TriangleList, submesh.Value.NumIndices, submesh.Value.BaseIndex);
                    }

                    //foreach (var submesh in mesh.Submeshes)
                    //    _device.DrawIndexed(PrimitiveType.TriangleList, submesh.Value.NumIndices, submesh.Value.MeshBaseIndex);
                }

                _device.SetRasterizerState(_rasterizerWireframe);

                // Draw boxes
                if (DrawVisibilityBox || DrawCollisionBox)
                {
                    if (DrawVisibilityBox)
                    {
                        _vertexBufferVisibility?.Dispose();
                        _vertexBufferVisibility = GetVertexBufferFromBoundingBox(Static.VisibilityBox);

                        _device.SetVertexBuffer(_vertexBufferVisibility);
                        _device.SetVertexInputLayout(VertexInputLayout.FromBuffer(0, _vertexBufferVisibility));
                        _device.SetIndexBuffer(null, false);

                        solidEffect.Parameters["ModelViewProjection"].SetValue(viewProjection.ToSharpDX());
                        solidEffect.Parameters["Color"].SetValue(new Vector4(0.0f, 1.0f, 0.0f, 1.0f));
                        solidEffect.CurrentTechnique.Passes[0].Apply();

                        _device.Draw(PrimitiveType.LineList, _vertexBufferVisibility.ElementCount);
                    }

                    if (DrawCollisionBox)
                    {
                        _vertexBufferCollision?.Dispose();
                        _vertexBufferCollision = GetVertexBufferFromBoundingBox(Static.CollisionBox);

                        _device.SetVertexBuffer(_vertexBufferCollision);
                        _device.SetVertexInputLayout(VertexInputLayout.FromBuffer(0, _vertexBufferCollision));
                        _device.SetIndexBuffer(null, false);

                        solidEffect.Parameters["ModelViewProjection"].SetValue(viewProjection.ToSharpDX());
                        solidEffect.Parameters["Color"].SetValue(new Vector4(1.0f, 0.0f, 0.0f, 1.0f));
                        solidEffect.CurrentTechnique.Passes[0].Apply();

                        _device.Draw(PrimitiveType.LineList, _vertexBufferCollision.ElementCount);
                    }
                }

                // Draw normals
                if (DrawNormals)
                {
                    var lines = new List <SolidVertex>();
                    for (int i = 0; i < Static.Mesh.VerticesNormals.Count; i++)
                    {
                        var p = Vector3.Transform(Static.Mesh.VerticesPositions[i], world);
                        var n = Vector3.TransformNormal(Static.Mesh.VerticesNormals[i] /
                                                        Static.Mesh.VerticesNormals[i].Length(), world);

                        var v = new SolidVertex();
                        v.Position = p;
                        v.Color    = new Vector4(1.0f, 1.0f, 1.0f, 1.0f);
                        lines.Add(v);

                        v          = new SolidVertex();
                        v.Position = p + n * 256.0f;
                        v.Color    = new Vector4(1.0f, 1.0f, 1.0f, 1.0f);
                        lines.Add(v);
                    }

                    Buffer <SolidVertex> bufferLines = Buffer.New(_device, lines.ToArray(), BufferFlags.VertexBuffer, SharpDX.Direct3D11.ResourceUsage.Default);
                    _device.SetVertexBuffer(bufferLines);
                    _device.SetVertexInputLayout(VertexInputLayout.FromBuffer(0, bufferLines));
                    _device.SetIndexBuffer(null, false);

                    solidEffect.Parameters["ModelViewProjection"].SetValue(viewProjection.ToSharpDX());
                    solidEffect.Parameters["Color"].SetValue(new Vector4(1.0f, 1.0f, 1.0f, 1.0f));
                    solidEffect.CurrentTechnique.Passes[0].Apply();

                    _device.Draw(PrimitiveType.LineList, bufferLines.ElementCount);
                }
            }

            if (DrawGrid)
            {
                _device.SetRasterizerState(_rasterizerWireframe);

                // Draw the grid
                _device.SetVertexBuffer(0, _plane.VertexBuffer);
                _device.SetVertexInputLayout(VertexInputLayout.FromBuffer(0, _plane.VertexBuffer));
                _device.SetIndexBuffer(_plane.IndexBuffer, true);

                solidEffect.Parameters["ModelViewProjection"].SetValue(viewProjection.ToSharpDX());
                solidEffect.Parameters["Color"].SetValue(Vector4.One);
                solidEffect.Techniques[0].Passes[0].Apply();

                _device.Draw(PrimitiveType.LineList, _plane.VertexBuffer.ElementCount);
            }

            if (DrawLights)
            {
                _device.SetRasterizerState(_rasterizerWireframe);

                foreach (var light in Static.Lights)
                {
                    // Draw the little sphere
                    _device.SetVertexBuffer(0, _littleSphere.VertexBuffer);
                    _device.SetVertexInputLayout(VertexInputLayout.FromBuffer(0, _littleSphere.VertexBuffer));
                    _device.SetIndexBuffer(_littleSphere.IndexBuffer, false);

                    var world = Matrix4x4.CreateTranslation(light.Position);
                    solidEffect.Parameters["ModelViewProjection"].SetValue((world * viewProjection).ToSharpDX());
                    solidEffect.Parameters["Color"].SetValue(new Vector4(1.0f, 1.0f, 0.0f, 1.0f));
                    solidEffect.Techniques[0].Passes[0].Apply();

                    _device.DrawIndexed(PrimitiveType.TriangleList, _littleSphere.IndexBuffer.ElementCount);

                    if (SelectedLight == light)
                    {
                        _device.SetVertexBuffer(0, _sphere.VertexBuffer);
                        _device.SetVertexInputLayout(VertexInputLayout.FromBuffer(0, _sphere.VertexBuffer));
                        _device.SetIndexBuffer(_sphere.IndexBuffer, false);

                        world = Matrix4x4.CreateScale(light.Radius * 2.0f) * Matrix4x4.CreateTranslation(light.Position);
                        solidEffect.Parameters["ModelViewProjection"].SetValue((world * viewProjection).ToSharpDX());
                        solidEffect.Parameters["Color"].SetValue(new Vector4(0.0f, 1.0f, 0.0f, 1.0f));
                        solidEffect.Techniques[0].Passes[0].Apply();

                        _device.DrawIndexed(PrimitiveType.TriangleList, _sphere.IndexBuffer.ElementCount);
                    }
                }

                _device.SetRasterizerState(_device.RasterizerStates.CullBack);
            }

            if (DrawGizmo)
            {
                // Draw the gizmo
                SwapChain.ClearDepth();
                _gizmo.Draw(viewProjection);
            }

            if (SelectedLight != null)
            {
                // Draw the gizmo of selected light
                SwapChain.ClearDepth();
                _gizmoLight.Draw(viewProjection);
            }

            // Draw debug strings
            ((TombLib.Rendering.DirectX11.Dx11RenderingDevice)Device).ResetState(); // To make sure SharpDx.Toolkit didn't change settings.
            SwapChain.RenderText(new Text
            {
                Font      = _fontDefault,
                PixelPos  = new Vector2(5, 5),
                Alignment = new Vector2(0, 0),
                String    =
                    "Position: " + StaticPosition +
                    "\nRotation: " + StaticRotation.X * (180 / Math.PI) +
                    "\nScale: " + StaticScale
            });
        }
Пример #6
0
            /// <summary>
            /// Creates a sphere primitive.
            /// </summary>
            /// <param name="device">The device.</param>
            /// <param name="diameter">The diameter.</param>
            /// <param name="tessellation">The tessellation.</param>
            /// <param name="toLeftHanded">if set to <c>true</c> vertices and indices will be transformed to left handed. Default is true.</param>
            /// <returns>A sphere primitive.</returns>
            /// <exception cref="System.ArgumentOutOfRangeException">tessellation;Must be >= 3</exception>
            public static GeometricPrimitive New(GraphicsDevice device, float diameter = 1.0f, float length = 1.0f, int tessellation = 18, bool toLeftHanded = false)
            {
                if (tessellation < 3)
                {
                    throw new ArgumentOutOfRangeException(nameof(tessellation), "Must be >= 3");
                }

                int verticalSegments   = tessellation;
                int horizontalSegments = tessellation * 2;

                var vertices = new SolidVertex[(verticalSegments + 1) * (horizontalSegments + 1)];
                var indices  = new int[verticalSegments * (horizontalSegments + 1) * 6];

                float radius = diameter / 2;

                // Vertex of the cone
                float angle = (float)(2 * Math.PI / tessellation);

                List <SolidVertex> tempVertices = new List <SolidVertex>();
                List <int>         tempIndices  = new List <int>();

                for (int i = 0; i < verticalSegments; i++)
                {
                    float x = radius * (float)Math.Sin(i * angle);
                    float y = radius * (float)Math.Cos(i * angle);
                    float z = length;

                    tempVertices.Add(new SolidVertex(new Vector3(x, y, z)));
                }

                tempVertices.Add(new SolidVertex(new Vector3(0.0f, 0.0f, 0.0f)));

                for (int i = 0; i < tessellation; i++)
                {
                    int first = i;
                    int last  = i == tessellation - 1 ? 0 : i + 1;
                    int cone  = tempVertices.Count - 1;

                    tempIndices.Add(cone);
                    tempIndices.Add(first);
                    tempIndices.Add(last);
                }

                // Create rings of vertices at progressively higher latitudes.

                /* for (int i = 0; i <= verticalSegments; i++)
                 * {
                 *   float v = 1.0f - (float)i / verticalSegments;
                 *
                 *   var latitude = (float)((i * Math.PI / verticalSegments) - Math.PI / 2.0);
                 *   var dy = (float)Math.Sin(latitude);
                 *   var dxz = (float)Math.Cos(latitude);
                 *
                 *   // Create a single ring of vertices at this latitude.
                 *   for (int j = 0; j <= horizontalSegments; j++)
                 *   {
                 *       float u = (float)j / horizontalSegments;
                 *
                 *       var longitude = (float)(j * 2.0 * Math.PI / horizontalSegments);
                 *       var dx = (float)Math.Sin(longitude);
                 *       var dz = (float)Math.Cos(longitude);
                 *
                 *       dx *= dxz;
                 *       dz *= dxz;
                 *
                 *       var normal = new Vector3(dx, dy, dz);
                 *       var textureCoordinate = new Vector2(u, v);
                 *
                 *       SolidVertex vertex = new TombLib.LevelData.SolidVertex();
                 *       vertex.Position = new Vector4(normal * radius, 1);
                 *       vertex.Normal = normal;
                 *       vertex.UV = textureCoordinate;
                 *
                 *       vertices[vertexCount++] = vertex;
                 *   }
                 * }
                 *
                 * // Fill the index buffer with triangles joining each pair of latitude rings.
                 * int stride = horizontalSegments + 1;
                 *
                 * int indexCount = 0;
                 * for (int i = 0; i < verticalSegments; i++)
                 * {
                 *   for (int j = 0; j <= horizontalSegments; j++)
                 *   {
                 *       int nextI = i + 1;
                 *       int nextJ = (j + 1) % stride;
                 *
                 *       indices[indexCount++] = (i * stride + nextJ);
                 *       indices[indexCount++] = (nextI * stride + j);
                 *       indices[indexCount++] = (i * stride + j);
                 *
                 *       indices[indexCount++] = (nextI * stride + nextJ);
                 *       indices[indexCount++] = (nextI * stride + j);
                 *       indices[indexCount++] = (i * stride + nextJ);
                 *   }
                 * }*/

                vertices = tempVertices.ToArray();
                indices  = tempIndices.ToArray();

                // Create the primitive object.
                return(new GeometricPrimitive(device, vertices, indices, toLeftHanded)
                {
                    Name = "Sphere"
                });
            }