Example #1
0
        /// <summary></summary>
        public void Dispose()
        {
            DisposeMember(ref positionSizeBufferA);
            DisposeMember(ref velocityRotationBufferA);
            DisposeMember(ref userBufferA);
            DisposeMember(ref colourBufferA);

            DisposeMember(ref positionSizeBufferB);
            DisposeMember(ref velocityRotationBufferB);
            DisposeMember(ref userBufferB);
            DisposeMember(ref colourBufferB);

            DisposeMember(ref lifeStoreBufferA);
            DisposeMember(ref lifeStoreBufferB);

            DisposeMember(ref mrtGroupA);
            DisposeMember(ref mrtGroupB);

            lifeStepParticleData = null;
            allProcessors        = null;
            activeRenderPass     = null;
            verticesRenderIndex  = null;
            scissorTest          = null;
            backgroundFillPass   = null;
            randomTexture        = null;

            shaderRandomValues = null;
        }
Example #2
0
        private void GenCubeVS(DrawState state)
        {
            if (cubeVS != null)
            {
                return;
            }
            cubeVS = state.UserValues[cubeVSid] as IVertices;
            if (cubeVS != null)
            {
                return;
            }

            //cube outlines, between 0,0,0 and 1,1,1
            cubeVS = new Vertices <Vector3>(
                new Vector3(0, 0, 0), new Vector3(1, 0, 0), new Vector3(0, 1, 0), new Vector3(1, 1, 0),
                new Vector3(0, 0, 1), new Vector3(1, 0, 1), new Vector3(0, 1, 1), new Vector3(1, 1, 1),

                new Vector3(0, 0, 0), new Vector3(0, 1, 0), new Vector3(1, 0, 0), new Vector3(1, 1, 0),
                new Vector3(0, 0, 1), new Vector3(0, 1, 1), new Vector3(1, 0, 1), new Vector3(1, 1, 1),

                new Vector3(0, 0, 0), new Vector3(0, 0, 1), new Vector3(1, 0, 0), new Vector3(1, 0, 1),
                new Vector3(0, 1, 0), new Vector3(0, 1, 1), new Vector3(1, 1, 0), new Vector3(1, 1, 1)
                );
            state.UserValues[cubeVSid] = cubeVS;
        }
    public static Vector3 CalculateCenter(this IVertices source)
    {
        var sum = Vector3.zero;

        source.Vertices.ForEach(v => sum += v.Position);
        return(sum / source.Vertices.Count);
    }
Example #4
0
        /// <summary>Generates a vertex buffer used for drawing lines in GPU or CPU batches</summary>
        public static void GenerateLinesVertices(DrawState state, ref IVertices vertices)
        {
            if (vertices != null)
            {
                return;
            }

            vertices = state.UserValues[verticesID] as IVertices;

            if (vertices != null)
            {
                return;
            }

            //4096 will be approx 256kb (however there is only one copy for the entire app)
#if XBOX360
            int maxVerts = 4096;
#else
            int maxVerts = ParticleSystem.SystemSupportsGpuParticles ? 4096 : 512;
#endif

            Vector2[] vertexData = new Vector2[maxVerts * 2];

            int v = 0;
            for (int n = 0; n < maxVerts; n++)
            {
                vertexData[v++] = new Vector2(n, -1);
                vertexData[v++] = new Vector2(n, 1);
            }

            vertices = Vertices <Vector2> .CreateSingleElementVertices(vertexData, VertexElementUsage.Position, 0);

            state.UserValues[verticesID] = vertices;
        }
Example #5
0
 /// <summary>
 /// Create a Geometry object.
 /// </summary>
 /// <param name="device">The graphics device to create the geometry on.</param>
 /// <param name="primitiveType">The type of primitive used to draw the geometry.</param>
 /// <param name="vertices">The vertices of the geometry.</param>
 public Geometry(GraphicsDevice device, PrimitiveType primitiveType, IVertices vertices)
 {
     XiHelper.ArgumentNullCheck(device, vertices);
     this.device = device;
     this.primitiveType = primitiveType;
     vertexSize = vertices.VertexSize;
     vertexCount = vertices.Length;
     vertexBuffer = new VertexBuffer(device, vertices.Length * vertices.VertexSize, BufferUsage.None);
     vertices.SetDataOfVertexBuffer(vertexBuffer);
     primitiveCount = primitiveType.GetPrimitiveCount(vertices.Length);
     vertexDeclaration = new ManagedVertexDeclaration(device, vertices.VertexElements);
 }
Example #6
0
 internal void SetChild(int index, IVertices child)
 {
     if (buffers[index] != child)
     {
         buffers[index] = child;
         if (child.VertexType != bufferTypes[index])
         {
             decl = null;
             bufferTypes[index] = child.VertexType;
         }
     }
 }
Example #7
0
        /// <summary>
        /// Construct the cube with the given minimum and maximum bound
        /// </summary>
        /// <param name="min"></param>
        /// <param name="max"></param>
        public Cube(Vector3 min, Vector3 max)
        {
            this.min = min;
            this.max = max;

            Vector3 size = max - min;

            //yeah ok
            verts = new Vertices <VertexPositionNormalTexture>(
                new VertexPositionNormalTexture(new Vector3(0, 0, 0) * size + min, new Vector3(-1, 0, 0), new Vector2(0, 0)),
                new VertexPositionNormalTexture(new Vector3(0, 1, 0) * size + min, new Vector3(-1, 0, 0), new Vector2(1, 0)),
                new VertexPositionNormalTexture(new Vector3(0, 1, 1) * size + min, new Vector3(-1, 0, 0), new Vector2(1, 1)),
                new VertexPositionNormalTexture(new Vector3(0, 0, 1) * size + min, new Vector3(-1, 0, 0), new Vector2(0, 1)),

                new VertexPositionNormalTexture(new Vector3(0, 0, 0) * size + min, new Vector3(0, -1, 0), new Vector2(1, 0)),
                new VertexPositionNormalTexture(new Vector3(1, 0, 0) * size + min, new Vector3(0, -1, 0), new Vector2(0, 0)),
                new VertexPositionNormalTexture(new Vector3(1, 0, 1) * size + min, new Vector3(0, -1, 0), new Vector2(0, 1)),
                new VertexPositionNormalTexture(new Vector3(0, 0, 1) * size + min, new Vector3(0, -1, 0), new Vector2(1, 1)),

                new VertexPositionNormalTexture(new Vector3(0, 0, 0) * size + min, new Vector3(0, 0, -1), new Vector2(0, 0)),
                new VertexPositionNormalTexture(new Vector3(1, 0, 0) * size + min, new Vector3(0, 0, -1), new Vector2(1, 0)),
                new VertexPositionNormalTexture(new Vector3(1, 1, 0) * size + min, new Vector3(0, 0, -1), new Vector2(1, 1)),
                new VertexPositionNormalTexture(new Vector3(0, 1, 0) * size + min, new Vector3(0, 0, -1), new Vector2(0, 1)),


                new VertexPositionNormalTexture(new Vector3(1, 0, 0) * size + min, new Vector3(1, 0, 0), new Vector2(1, 1)),
                new VertexPositionNormalTexture(new Vector3(1, 1, 0) * size + min, new Vector3(1, 0, 0), new Vector2(0, 1)),
                new VertexPositionNormalTexture(new Vector3(1, 1, 1) * size + min, new Vector3(1, 0, 0), new Vector2(0, 0)),
                new VertexPositionNormalTexture(new Vector3(1, 0, 1) * size + min, new Vector3(1, 0, 0), new Vector2(1, 0)),

                new VertexPositionNormalTexture(new Vector3(0, 1, 0) * size + min, new Vector3(0, 1, 0), new Vector2(0, 1)),
                new VertexPositionNormalTexture(new Vector3(1, 1, 0) * size + min, new Vector3(0, 1, 0), new Vector2(1, 1)),
                new VertexPositionNormalTexture(new Vector3(1, 1, 1) * size + min, new Vector3(0, 1, 0), new Vector2(1, 0)),
                new VertexPositionNormalTexture(new Vector3(0, 1, 1) * size + min, new Vector3(0, 1, 0), new Vector2(0, 0)),

                new VertexPositionNormalTexture(new Vector3(0, 0, 1) * size + min, new Vector3(0, 0, 1), new Vector2(1, 1)),
                new VertexPositionNormalTexture(new Vector3(1, 0, 1) * size + min, new Vector3(0, 0, 1), new Vector2(0, 1)),
                new VertexPositionNormalTexture(new Vector3(1, 1, 1) * size + min, new Vector3(0, 0, 1), new Vector2(0, 0)),
                new VertexPositionNormalTexture(new Vector3(0, 1, 1) * size + min, new Vector3(0, 0, 1), new Vector2(1, 0))
                );

            inds = new Indices <ushort>(
                0 + 0, 1 + 0, 2 + 0, 0 + 0, 2 + 0, 3 + 0,
                0 + 4, 2 + 4, 1 + 4, 0 + 4, 3 + 4, 2 + 4,
                0 + 8, 1 + 8, 2 + 8, 0 + 8, 2 + 8, 3 + 8,

                0 + 12, 2 + 12, 1 + 12, 0 + 12, 3 + 12, 2 + 12,
                0 + 16, 1 + 16, 2 + 16, 0 + 16, 2 + 16, 3 + 16,
                0 + 20, 2 + 20, 1 + 20, 0 + 20, 3 + 20, 2 + 20
                );
        }
Example #8
0
        /// <summary>
        /// Construct the cube with the given size
        /// </summary>
        /// <param name="size"></param>
        public Cube(Vector3 size)
        {
            Vector3 absSize = new Vector3(Math.Abs(size.X), Math.Abs(size.Y), Math.Abs(size.Z));

            this.min = -absSize;
            this.max = absSize;

            //yeah ok
            verts = new Vertices <VertexPositionNormalTexture>(
                new VertexPositionNormalTexture(new Vector3(-1, -1, -1) * size, new Vector3(-1, 0, 0), new Vector2(0, 0)),
                new VertexPositionNormalTexture(new Vector3(-1, 1, -1) * size, new Vector3(-1, 0, 0), new Vector2(1, 0)),
                new VertexPositionNormalTexture(new Vector3(-1, 1, 1) * size, new Vector3(-1, 0, 0), new Vector2(1, 1)),
                new VertexPositionNormalTexture(new Vector3(-1, -1, 1) * size, new Vector3(-1, 0, 0), new Vector2(0, 1)),

                new VertexPositionNormalTexture(new Vector3(-1, -1, -1) * size, new Vector3(0, -1, 0), new Vector2(1, 0)),
                new VertexPositionNormalTexture(new Vector3(1, -1, -1) * size, new Vector3(0, -1, 0), new Vector2(0, 0)),
                new VertexPositionNormalTexture(new Vector3(1, -1, 1) * size, new Vector3(0, -1, 0), new Vector2(0, 1)),
                new VertexPositionNormalTexture(new Vector3(-1, -1, 1) * size, new Vector3(0, -1, 0), new Vector2(1, 1)),

                new VertexPositionNormalTexture(new Vector3(-1, -1, -1) * size, new Vector3(0, 0, -1), new Vector2(0, 0)),
                new VertexPositionNormalTexture(new Vector3(1, -1, -1) * size, new Vector3(0, 0, -1), new Vector2(1, 0)),
                new VertexPositionNormalTexture(new Vector3(1, 1, -1) * size, new Vector3(0, 0, -1), new Vector2(1, 1)),
                new VertexPositionNormalTexture(new Vector3(-1, 1, -1) * size, new Vector3(0, 0, -1), new Vector2(0, 1)),


                new VertexPositionNormalTexture(new Vector3(1, -1, -1) * size, new Vector3(1, 0, 0), new Vector2(1, 1)),
                new VertexPositionNormalTexture(new Vector3(1, 1, -1) * size, new Vector3(1, 0, 0), new Vector2(0, 1)),
                new VertexPositionNormalTexture(new Vector3(1, 1, 1) * size, new Vector3(1, 0, 0), new Vector2(0, 0)),
                new VertexPositionNormalTexture(new Vector3(1, -1, 1) * size, new Vector3(1, 0, 0), new Vector2(1, 0)),

                new VertexPositionNormalTexture(new Vector3(-1, 1, -1) * size, new Vector3(0, 1, 0), new Vector2(0, 1)),
                new VertexPositionNormalTexture(new Vector3(1, 1, -1) * size, new Vector3(0, 1, 0), new Vector2(1, 1)),
                new VertexPositionNormalTexture(new Vector3(1, 1, 1) * size, new Vector3(0, 1, 0), new Vector2(1, 0)),
                new VertexPositionNormalTexture(new Vector3(-1, 1, 1) * size, new Vector3(0, 1, 0), new Vector2(0, 0)),

                new VertexPositionNormalTexture(new Vector3(-1, -1, 1) * size, new Vector3(0, 0, 1), new Vector2(1, 1)),
                new VertexPositionNormalTexture(new Vector3(1, -1, 1) * size, new Vector3(0, 0, 1), new Vector2(0, 1)),
                new VertexPositionNormalTexture(new Vector3(1, 1, 1) * size, new Vector3(0, 0, 1), new Vector2(0, 0)),
                new VertexPositionNormalTexture(new Vector3(-1, 1, 1) * size, new Vector3(0, 0, 1), new Vector2(1, 0))
                );

            inds = new Indices <ushort>(
                0 + 0, 1 + 0, 2 + 0, 0 + 0, 2 + 0, 3 + 0,
                0 + 4, 2 + 4, 1 + 4, 0 + 4, 3 + 4, 2 + 4,
                0 + 8, 1 + 8, 2 + 8, 0 + 8, 2 + 8, 3 + 8,

                0 + 12, 2 + 12, 1 + 12, 0 + 12, 3 + 12, 2 + 12,
                0 + 16, 1 + 16, 2 + 16, 0 + 16, 2 + 16, 3 + 16,
                0 + 20, 2 + 20, 1 + 20, 0 + 20, 3 + 20, 2 + 20
                );
        }
		/// <summary>
		/// Construct the cube with the given size
		/// </summary>
		/// <param name="size"></param>
		public Cube(Vector3 size)
		{
			Vector3 absSize = new Vector3(Math.Abs(size.X), Math.Abs(size.Y), Math.Abs(size.Z));
			this.min = -absSize;
			this.max = absSize;

			//yeah ok
			verts = new Vertices<VertexPositionNormalTexture>(
				new VertexPositionNormalTexture(new Vector3(-1,-1,-1) * size,new Vector3(-1,0,0), new Vector2(0,0)),
				new VertexPositionNormalTexture(new Vector3(-1, 1,-1) * size,new Vector3(-1,0,0), new Vector2(1,0)),
				new VertexPositionNormalTexture(new Vector3(-1, 1, 1) * size,new Vector3(-1,0,0), new Vector2(1,1)),
				new VertexPositionNormalTexture(new Vector3(-1,-1, 1) * size,new Vector3(-1,0,0), new Vector2(0,1)),
				
				new VertexPositionNormalTexture(new Vector3(-1, -1,-1) * size,new Vector3(0,-1,0), new Vector2(1,0)),
				new VertexPositionNormalTexture(new Vector3( 1, -1,-1) * size,new Vector3(0,-1,0), new Vector2(0,0)),
				new VertexPositionNormalTexture(new Vector3( 1, -1, 1) * size,new Vector3(0,-1,0), new Vector2(0,1)),
				new VertexPositionNormalTexture(new Vector3(-1, -1, 1) * size,new Vector3(0,-1,0), new Vector2(1,1)),
				
				new VertexPositionNormalTexture(new Vector3(-1,-1,-1) * size,new Vector3(0,0,-1), new Vector2(0,0)),
				new VertexPositionNormalTexture(new Vector3( 1,-1,-1) * size,new Vector3(0,0,-1), new Vector2(1,0)),
				new VertexPositionNormalTexture(new Vector3( 1, 1,-1) * size,new Vector3(0,0,-1), new Vector2(1,1)),
				new VertexPositionNormalTexture(new Vector3(-1, 1,-1) * size,new Vector3(0,0,-1), new Vector2(0,1)),

				
				new VertexPositionNormalTexture(new Vector3(1,-1,-1) * size,new Vector3(1,0,0), new Vector2(1,1)),
				new VertexPositionNormalTexture(new Vector3(1, 1,-1) * size,new Vector3(1,0,0), new Vector2(0,1)),
				new VertexPositionNormalTexture(new Vector3(1, 1, 1) * size,new Vector3(1,0,0), new Vector2(0,0)),
				new VertexPositionNormalTexture(new Vector3(1,-1, 1) * size,new Vector3(1,0,0), new Vector2(1,0)),
				
				new VertexPositionNormalTexture(new Vector3(-1, 1,-1) * size,new Vector3(0,1,0), new Vector2(0,1)),
				new VertexPositionNormalTexture(new Vector3( 1, 1,-1) * size,new Vector3(0,1,0), new Vector2(1,1)),
				new VertexPositionNormalTexture(new Vector3( 1, 1, 1) * size,new Vector3(0,1,0), new Vector2(1,0)),
				new VertexPositionNormalTexture(new Vector3(-1, 1, 1) * size,new Vector3(0,1,0), new Vector2(0,0)),
				
				new VertexPositionNormalTexture(new Vector3(-1,-1,1) * size,new Vector3(0,0,1), new Vector2(1,1)),
				new VertexPositionNormalTexture(new Vector3( 1,-1,1) * size,new Vector3(0,0,1), new Vector2(0,1)),
				new VertexPositionNormalTexture(new Vector3( 1, 1,1) * size,new Vector3(0,0,1), new Vector2(0,0)),
				new VertexPositionNormalTexture(new Vector3(-1, 1,1) * size,new Vector3(0,0,1), new Vector2(1,0))
			);

			inds = new Indices<ushort>(
				0 + 0, 1 + 0, 2 + 0, 0 + 0, 2 + 0, 3 + 0,
				0 + 4, 2 + 4, 1 + 4, 0 + 4, 3 + 4, 2 + 4,
				0 + 8, 1 + 8, 2 + 8, 0 + 8, 2 + 8, 3 + 8,

				0 + 12, 2 + 12, 1 + 12, 0 + 12, 3 + 12, 2 + 12,
				0 + 16, 1 + 16, 2 + 16, 0 + 16, 2 + 16, 3 + 16,
				0 + 20, 2 + 20, 1 + 20, 0 + 20, 3 + 20, 2 + 20
			);
		}
Example #10
0
        /// <summary>
        /// Get global vertices/indices for drawing billboards
        /// </summary>
        /// <param name="state"></param>
        /// <param name="vertices"></param>
        /// <param name="indices"></param>
        public static void GenerateBillboardVertices(DrawState state, ref IVertices vertices, ref IIndices indices)
        {
            if (vertices != null)
            {
                return;
            }

            vertices = state.UserValues[verticesID] as IVertices;
            indices  = state.UserValues[indicesID] as IIndices;

            if (vertices != null)
            {
                return;
            }

            //8192 will be approx 512kb (however there is only one copy for the entire app)
#if XBOX360
            int maxVerts = 8192;
#else
            int maxVerts = ParticleSystem.SystemSupportsGpuParticles ? 8192 : 512;
#endif

            Vector4[] vertexData = new Vector4[maxVerts * 4];
            ushort[]  indexData  = new ushort[maxVerts * 6];

            int v = 0;
            int i = 0;
            for (int n = 0; n < maxVerts; n++)
            {
                vertexData[v++] = new Vector4(n, -1, 1, 0);
                vertexData[v++] = new Vector4(n, 1, 1, 0);
                vertexData[v++] = new Vector4(n, 1, -1, 0);
                vertexData[v++] = new Vector4(n, -1, -1, 0);

                indexData[i++] = (ushort)(n * 4 + 0);
                indexData[i++] = (ushort)(n * 4 + 1);
                indexData[i++] = (ushort)(n * 4 + 2);

                indexData[i++] = (ushort)(n * 4 + 0);
                indexData[i++] = (ushort)(n * 4 + 2);
                indexData[i++] = (ushort)(n * 4 + 3);
            }

            vertices = new Vertices <Vector4>(vertexData);
            indices  = new Indices <ushort>(indexData);

            state.UserValues[verticesID] = vertices;
            state.UserValues[indicesID]  = indices;
        }
Example #11
0
        public DarkGroundPlane(Vector4 colour)
        {
            this.colour = colour;

            //make a ground plane using two triangles
            float extents = 1000;

            Vector3[] positions = new Vector3[]
            {
                new Vector3(-extents, -5, -extents),
                new Vector3(extents, -5, -extents),
                new Vector3(-extents, -5, extents),
                new Vector3(extents, -5, extents),
            };

            this.vertices = new Vertices <Vector3>(positions);
        }
Example #12
0
        public GroundLightDisk(Vector3 position)
        {
            Matrix.CreateTranslation(ref position, out worldMatrix);

            const int vertCount = 32;

            //make a ground plane using two triangles
            //this is a bit nasty as the vertex buffer is recreated for each fire
            VertexPositionColor[] verts = new VertexPositionColor[vertCount + 2];
            //create vertices in a circle. The first vertex is in the centre. (Triangle Fan)
            verts[0] = new VertexPositionColor(Vector3.Zero, new Color(64, 40, 20));
            for (int i = 0; i <= vertCount; i++)
            {
                float angle = ((float)i / (float)vertCount) * MathHelper.TwoPi;
                verts[i + 1] = new VertexPositionColor(new Vector3((float)Math.Sin(angle) * 3, 0, (float)Math.Cos(angle) * 3), Color.Black);
            }
            this.vertices = new Vertices <VertexPositionColor>(verts);
        }
Example #13
0
        public GroundDisk(ContentRegister content, float radius, MaterialLightCollection lights)
        {
            //build the disk
            VertexPositionNormalTexture[] vertexData = new VertexPositionNormalTexture[256];

            for (int i = 0; i < vertexData.Length; i++)
            {
                //a bunch of vertices, in a circle!
                float   angle    = (float)i / (float)vertexData.Length * MathHelper.TwoPi;
                Vector3 position = new Vector3((float)Math.Sin(angle), (float)Math.Cos(angle), 0);

                vertexData[i] = new VertexPositionNormalTexture(position * radius, new Vector3(0, 0, 1), new Vector2(position.X, position.Y));
            }
            this.vertices = new Vertices <VertexPositionNormalTexture>(vertexData);

            //create the material, and add to content
            this.material        = new MaterialShader();
            this.material.Lights = lights;
            content.Add(this);
        }
Example #14
0
        /// <summary>
        /// Setup the frequency data and source vertex buffer
        /// </summary>
        /// <param name="vertices"></param>
        /// <param name="repeatCount">Number of times the vertex data should be repeated</param>
        public StreamFrequency(IVertices vertices, int repeatCount)
        {
            layout = DataLayout.Stream0Geometry_Stream1InstanceData;

            if (vertices is VerticesGroup)
            {
                this.frequency      = new int[(vertices as VerticesGroup).ChildCount];
                this.indexFrequency = new int[(vertices as VerticesGroup).ChildCount];
                this.dataFrequency  = new int[(vertices as VerticesGroup).ChildCount];

                this.RepeatCount = repeatCount;
            }
            else
            {
                this.frequency      = new int[1];
                this.indexFrequency = new int[1];
                this.dataFrequency  = new int[1];

                this.indexFrequency[0] = repeatCount;
            }
        }
Example #15
0
        internal static void AllocateVertices(DrawState state, ref IVertices vertices)
        {
            if (vertices == null)
            {
                vertices = state.Application.UserValues[vertexObjectNameRenderIndex] as IVertices;

                if (vertices == null)
                {
                    //this buffer may also be used for rendering the particles
                    Vector4[] vertexData = new Vector4[512];
                    for (int i = 0; i < vertexData.Length; i++)
                    {
                        vertexData[i] = new Vector4((float)i, (float)(i / 4), (float)(i % 4), 0);
                    }

                    vertices = new Vertices <Vector4>(vertexData);
                    vertices.ResourceUsage = ResourceUsage.Points;
                    state.Application.UserValues[vertexObjectNameRenderIndex] = vertices;
                }
            }
        }
Example #16
0
        //
        // NOTE:
        //
        // ----------------------
        //  New to Xen 1.6.3:
        // ----------------------
        //
        // The DrawState object has had the methods 'DrawDynamicVertices<>' and 'DrawDynamicIndexedVertices<>' added.
        // These methods wrap XNA DrawUserPrimitives and DrawUserIndexedPrimitives. Like existing Vertices<> objects,
        // these methods take care of the VertexDeclaration and render state for your.
        //
        // For volatile dynamic data (data that changes every frame) these methods are just as efficient as the
        // method demonstrated in this example. In some cases, it can be simpler to use this method too.
        //
        // These methods do not require a Vertices<> or Indices<> object, as they copy the entire vertex/index array
        // every frame when you make the draw call.
        //
        // For dynamic data that may not change every frame, using the method in this example is recommended.
        //

        //setup and create the vertices/indices
        public DynamicQuadGeometry()
        {
            //create the array of custom vertices, to form a quad
            this.vertexData = new CustomVertex[4]
            {
                new CustomVertex(new Vector3(-1, -1, 0), Vector3.UnitZ),               // bottom left
                new CustomVertex(new Vector3(-1, 1, 0), Vector3.UnitZ),                // top left
                new CustomVertex(new Vector3(1, -1, 0), Vector3.UnitZ),                // bottom right
                new CustomVertex(new Vector3(1, 1, 0), Vector3.UnitZ),                 // top right
            };

            //create the buffers
            this.vertices = new Vertices <CustomVertex>(vertexData);

            this.indices = new Indices <ushort>(0, 1, 2, 1, 3, 2);            //this is a shortcut using params[] supporting constructor

            //NEW CODE
            //Set the resource usage of the vertices to Dynamic
            //This can only be set before the vertices are first used
            this.vertices.ResourceUsage = ResourceUsage.Dynamic;
        }
        public GroundDisk(ContentRegister content, MaterialLightCollection lights, float radius)
        {
            this.radius = radius;

            int vertexCount = 256;

            //create the vertices. Note the DiskVertex() constructor takes an angle/size
            DiskVertex[] verts = new DiskVertex[vertexCount];
            for (int i = 0; i < vertexCount; i++)
            {
                verts[i] = new DiskVertex((i / (float)(vertexCount - 1)) * MathHelper.TwoPi, radius, 0.05f);
            }

            //create the vertex buffer
            this.vertices = new Vertices <DiskVertex>(verts);


            //create the custom material for this geometry
            //the light collection has been passed into the constructor, although it
            //could easily be changed later (by changing material.Lights)
            this.material = new MaterialShader(lights);

            //By default, per-pixel lighting in the material shader does not do
            //specular reflection. This is because specular nearly triples the
            //complexity of the lighting calculation - which makes rendering slower
            //and reduces the maximum number of per-pixel lights supported from 4 to 2.
            material.UsePerPixelSpecular = true;

            //give the disk really bright specular for effect
            material.SpecularColour = new Vector3(1, 1, 1);
            material.DiffuseColour  = new Vector3(0.6f, 0.6f, 0.6f);
            material.SpecularPower  = 64;

            //setup the texture samples to use high quality anisotropic filtering
            material.TextureMapSampler = TextureSamplerState.AnisotropicHighFiltering;
            material.NormalMapSampler  = TextureSamplerState.AnisotropicLowFiltering;

            //load the textures for this material
            content.Add(this);
        }
Example #18
0
        protected override void DrawElement(DrawState state)
        {
            if (graph == null)
            {
                graph = state.UserValues[graphID] as IVertices;

                if (graph == null)
                {
                    float[] graphValues = new float[MaxGraphSamples];
                    for (int i = 0; i < MaxGraphSamples; i++)
                    {
                        graphValues[i] = (float)i;
                    }

                    this.graph = Vertices <float> .CreateSingleElementVertices(graphValues, VertexElementUsage.Position, 0);

                    state.UserValues[graphID] = this.graph;
                }
            }

            graph.Draw(state, null, PrimitiveType.LineStrip, this.values.Length - 1, 0, 0);
        }
Example #19
0
        //setup and create the vertices/indices
        public QuadGeometry()
        {
            //create an array of custom vertices to form a quad
            //(this is just a normal C# array)
            CustomVertex[] verts = new CustomVertex[]
            {
                new CustomVertex(new Vector3(-1, -1, 0), Vector3.UnitZ),               // bottom left
                new CustomVertex(new Vector3(-1, 1, 0), Vector3.UnitZ),                // top left
                new CustomVertex(new Vector3(1, -1, 0), Vector3.UnitZ),                // bottom right
                new CustomVertex(new Vector3(1, 1, 0), Vector3.UnitZ),                 // top right
            };

            //create the indices data array
            ushort[] inds = new ushort[]
            {
                0, 1, 2,               // first triangle	(bottom left -> top left -> bottom right)
                1, 3, 2                // second triangle	(top left -> top right -> bottom right)
            };

            //create the vertices/indices objects
            this.vertices = new Vertices <CustomVertex>(verts);
            this.indices  = new Indices <ushort>(inds);
        }
		//setup and create the vertices/indices
		public QuadGeometry()
		{
			//create an array of custom vertices to form a quad
			//(this is just a normal C# array)
			CustomVertex[] verts =
			{
				new CustomVertex(new Vector3(-1,-1,0), Vector3.UnitZ), // bottom left
				new CustomVertex(new Vector3(-1, 1,0), Vector3.UnitZ), // top left
				new CustomVertex(new Vector3( 1,-1,0), Vector3.UnitZ), // bottom right
				new CustomVertex(new Vector3( 1, 1,0), Vector3.UnitZ), // top right
			};

			//create the indices data array
			ushort[] inds =
			{
				0,1,2, // first triangle	(bottom left -> top left -> bottom right)
				1,3,2  // second triangle	(top left -> top right -> bottom right)
			};

			//create the vertices/indices objects
			this.vertices = new Vertices<CustomVertex>(verts);
			this.indices = new Indices<ushort>(inds);
		}
Example #21
0
		/// <summary>
		/// Static method to generate the geometry data used by the sphere
		/// </summary>
		public static void GenerateGeometry(Vector3 size, int tesselation, bool positionOnly, bool sizeToInternalCone, out IVertices vertices, out IIndices indices)
		{
			Cone geom = new Cone(size, tesselation, positionOnly, sizeToInternalCone);
			vertices = geom.verts;
			indices = geom.inds;
		}
		/// <summary>
		/// Static method to generate the geometry data used by the sphere
		/// </summary>
		public static void GenerateGeometry(Vector3 size, int tesselation, bool storePositionOnly, bool hemisphere, bool sizeToInternalSphere, out IVertices vertices, out IIndices indices)
		{
			Sphere sphere = new Sphere(size, tesselation, storePositionOnly, hemisphere, sizeToInternalSphere);
			vertices = sphere.verts;
			indices = sphere.inds;
		}
Example #23
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="size"></param>
        /// <param name="tesselation"></param>
        /// <param name="positionOnly">vertex data will only store position</param>
        /// <param name="sizeToInternalCone">expand the cone geometry outwards so it encoses the desired size</param>
        public Cone(Vector3 size, int tesselation, bool positionOnly, bool sizeToInternalCone)
        {
            if (tesselation <= 2)
            {
                throw new ArgumentException("tesselation is too small");
            }
            if (size.Z == 0)
            {
                throw new ArgumentException("size.Z == 0");
            }

            this.radius = 0;
            //this.radius = Math.Max(Math.Abs(size.X), Math.Max(Math.Abs(size.Y), Math.Abs(size.Z)));

            //if true, then a cone of 'size' should not intersect if placed within this mesh.
            //since the resolution isn't limitless, the flat surfaces will make the internal size slightly smaller.
            //so expand to compensate
            if (sizeToInternalCone)
            {
                float s = 1.0f / (float)Math.Cos(Math.PI / tesselation);
                size.X *= s;
                size.Y *= s;
            }
            geometryRadius = Math.Max(Math.Abs(size.X), Math.Max(Math.Abs(size.Y), Math.Abs(size.Z)));

            float tes            = tesselation;
            int   prevCount      = -1;
            int   startIndex     = 0;
            int   prevStartIndex = 0;
            List <VertexPositionNormalTexture> verts = new List <VertexPositionNormalTexture>();
            List <Vector3> vertsPos = new List <Vector3>();
            List <ushort>  inds     = new List <ushort>();

            if (positionOnly)
            {
                vertsPos.Add(Vector3.Zero);
            }
            else
            {
                verts.Add(new VertexPositionNormalTexture(Vector3.Zero, Vector3.Zero, new Vector2(0.5f, 0.5f)));
            }

            int y_count = tesselation;

            for (int y = 0; y < y_count; y++)
            {
                float ay  = y / tes * (float)Math.PI * 2.0f;
                int   div = (int)(tesselation * 2 * (float)Math.Sin(ay)) + 1;


                Vector3 norm = new Vector3((float)Math.Cos(ay), (float)Math.Sin(ay), 1);
                Vector3 pos  = norm * size;
                this.radius = Math.Max(this.radius, pos.LengthSquared());
                Vector2 tex = new Vector2(norm.X * 0.5f + 0.5f, norm.Y * 0.5f + 0.5f);

                if (positionOnly)
                {
                    vertsPos.Add(pos);
                }
                else
                {
                    verts.Add(new VertexPositionNormalTexture(pos, new Vector3(0, 0, Math.Sign(size.Z)), tex));
                }

                norm.X *= -size.Z / size.X;
                norm.Y *= -size.Z / size.Y;
                norm.Normalize();

                if (!positionOnly)
                {
                    verts.Add(new VertexPositionNormalTexture(pos, -norm, tex));
                }

                if (positionOnly)
                {
                    inds.Add(0);
                    inds.Add((ushort)(y + 1));
                    inds.Add((ushort)((y + 1) % y_count + 1));

                    if (y != 0 && y != y_count - 1)
                    {
                        inds.Add(1);
                        inds.Add((ushort)((y + 1) % y_count + 1));
                        inds.Add((ushort)(y + 1));
                    }
                }
                else
                {
                    inds.Add(0);
                    inds.Add((ushort)(y * 2 + 2));
                    inds.Add((ushort)(((y + 1) % y_count) * 2 + 2));

                    if (y != 0 && y != y_count - 1)
                    {
                        inds.Add(1);
                        inds.Add((ushort)(((y + 1) % y_count) * 2 + 1));
                        inds.Add((ushort)(y * 2 + 1));
                    }
                }

                prevCount      = div;
                prevStartIndex = startIndex;
                startIndex    += div;
            }

            if (this.radius != 0)
            {
                this.radius = (float)Math.Sqrt(this.radius);
            }

            if (positionOnly)
            {
                this.verts = new Vertices <Vector3>(vertsPos);
            }
            else
            {
                this.verts = new Vertices <VertexPositionNormalTexture>(verts);
            }
            this.inds = new Indices <ushort>(inds);
        }
Example #24
0
		/// <summary>
		/// Construct the cube with the given minimum and maximum bound
		/// </summary>
		/// <param name="min"></param>
		/// <param name="max"></param>
		public Cube(Vector3 min, Vector3 max)
		{
			this.min = min;
			this.max = max;

			Vector3 size = max - min;

			//yeah ok
			verts = new Vertices<VertexPositionNormalTexture>(
				new VertexPositionNormalTexture(new Vector3(0, 0, 0) * size + min, new Vector3(-1, 0, 0), new Vector2(0, 0)),
				new VertexPositionNormalTexture(new Vector3(0, 1, 0) * size + min, new Vector3(-1, 0, 0), new Vector2(1, 0)),
				new VertexPositionNormalTexture(new Vector3(0, 1, 1) * size + min, new Vector3(-1, 0, 0), new Vector2(1, 1)),
				new VertexPositionNormalTexture(new Vector3(0, 0, 1) * size + min, new Vector3(-1, 0, 0), new Vector2(0, 1)),

				new VertexPositionNormalTexture(new Vector3(0, 0, 0) * size + min, new Vector3(0, -1, 0), new Vector2(1, 0)),
				new VertexPositionNormalTexture(new Vector3(1, 0, 0) * size + min, new Vector3(0, -1, 0), new Vector2(0, 0)),
				new VertexPositionNormalTexture(new Vector3(1, 0, 1) * size + min, new Vector3(0, -1, 0), new Vector2(0, 1)),
				new VertexPositionNormalTexture(new Vector3(0, 0, 1) * size + min, new Vector3(0, -1, 0), new Vector2(1, 1)),

				new VertexPositionNormalTexture(new Vector3(0, 0, 0) * size + min, new Vector3(0, 0, -1), new Vector2(0, 0)),
				new VertexPositionNormalTexture(new Vector3(1, 0, 0) * size + min, new Vector3(0, 0, -1), new Vector2(1, 0)),
				new VertexPositionNormalTexture(new Vector3(1, 1, 0) * size + min, new Vector3(0, 0, -1), new Vector2(1, 1)),
				new VertexPositionNormalTexture(new Vector3(0, 1, 0) * size + min, new Vector3(0, 0, -1), new Vector2(0, 1)),


				new VertexPositionNormalTexture(new Vector3(1, 0, 0) * size + min, new Vector3(1, 0, 0), new Vector2(1, 1)),
				new VertexPositionNormalTexture(new Vector3(1, 1, 0) * size + min, new Vector3(1, 0, 0), new Vector2(0, 1)),
				new VertexPositionNormalTexture(new Vector3(1, 1, 1) * size + min, new Vector3(1, 0, 0), new Vector2(0, 0)),
				new VertexPositionNormalTexture(new Vector3(1, 0, 1) * size + min, new Vector3(1, 0, 0), new Vector2(1, 0)),

				new VertexPositionNormalTexture(new Vector3(0, 1, 0) * size + min, new Vector3(0, 1, 0), new Vector2(0, 1)),
				new VertexPositionNormalTexture(new Vector3(1, 1, 0) * size + min, new Vector3(0, 1, 0), new Vector2(1, 1)),
				new VertexPositionNormalTexture(new Vector3(1, 1, 1) * size + min, new Vector3(0, 1, 0), new Vector2(1, 0)),
				new VertexPositionNormalTexture(new Vector3(0, 1, 1) * size + min, new Vector3(0, 1, 0), new Vector2(0, 0)),

				new VertexPositionNormalTexture(new Vector3(0, 0, 1) * size + min, new Vector3(0, 0, 1), new Vector2(1, 1)),
				new VertexPositionNormalTexture(new Vector3(1, 0, 1) * size + min, new Vector3(0, 0, 1), new Vector2(0, 1)),
				new VertexPositionNormalTexture(new Vector3(1, 1, 1) * size + min, new Vector3(0, 0, 1), new Vector2(0, 0)),
				new VertexPositionNormalTexture(new Vector3(0, 1, 1) * size + min, new Vector3(0, 0, 1), new Vector2(1, 0))
			);

			inds = new Indices<ushort>(
				0 + 0, 1 + 0, 2 + 0, 0 + 0, 2 + 0, 3 + 0,
				0 + 4, 2 + 4, 1 + 4, 0 + 4, 3 + 4, 2 + 4,
				0 + 8, 1 + 8, 2 + 8, 0 + 8, 2 + 8, 3 + 8,

				0 + 12, 2 + 12, 1 + 12, 0 + 12, 3 + 12, 2 + 12,
				0 + 16, 1 + 16, 2 + 16, 0 + 16, 2 + 16, 3 + 16,
				0 + 20, 2 + 20, 1 + 20, 0 + 20, 3 + 20, 2 + 20
			);
		}
		public GroundDisk(ContentRegister content, float radius, MaterialLightCollection lights)
		{
			//build the disk
			var vertexData = new VertexPositionNormalTexture[256];
			var indices = new List<int>();

			for (int i = 1; i < vertexData.Length; i++)
			{
				//a bunch of vertices, in a circle!
				float angle = (float)(i-1) / (float)(vertexData.Length-2) * MathHelper.TwoPi;
				Vector3 position = new Vector3((float)Math.Sin(angle), (float)Math.Cos(angle), 0);

				vertexData[i] = new VertexPositionNormalTexture(position * radius, new Vector3(0, 0, 1), new Vector2(position.X, position.Y));
				if (i > 1)
				{
					indices.Add(0);
					indices.Add(i - 1);
					indices.Add(i);
				}
			}
			vertexData[0] = new VertexPositionNormalTexture(new Vector3(), new Vector3(0, 0, 1), new Vector2());

			this.vertices = new Vertices<VertexPositionNormalTexture>(vertexData);
			this.indices = new Indices<int>(indices);

			//create the material, and add to content
			this.material = new MaterialShader();
			this.material.LightCollection = lights;
			this.material.Textures = new MaterialTextures();

			content.Add(this);
		}
		/// <summary>
		/// Create spherical geometry
		/// </summary>
		/// <param name="size">Size of the sphere</param>
		/// <param name="tesselation">Tesselation of the sphere. Approx number of triangles will be tesselation*tesselation</param>
		/// <param name="storePositionOnly">Store only position, no normals or texture coordinates</param>
		/// <param name="hemisphere">Generate a hemisphere</param>
		/// <param name="sizeToInternalSphere">Expand the sphere to compensate for smaller internal size caused by low tesselation</param>
		public Sphere(Vector3 size, int tesselation, bool storePositionOnly, bool hemisphere, bool sizeToInternalSphere)
		{
			if (tesselation <= 1)
				throw new ArgumentException("tesselation is too small");
			this.radius = Math.Max(Math.Abs(size.X),Math.Max(Math.Abs(size.Y),Math.Abs(size.Z)));

			//if true, then a sphere of 'size' should not intersect if placed within this mesh.
			//since the resolution isn't limitless, the flat surfaces will make the internal size slightly smaller.
			//so expand to compensate
			if (sizeToInternalSphere)
			{
				size /= (float)Math.Cos(Math.PI / tesselation);
			}
			geometryRadius = Math.Max(Math.Abs(size.X), Math.Max(Math.Abs(size.Y), Math.Abs(size.Z)));

			float tes = tesselation;
			int prevCount = -1;
			int startIndex = 0;
			int prevStartIndex = 0;
			List<VertexPositionNormalTexture> verts = new List<VertexPositionNormalTexture>();
			List<Vector3> vertsPos = new List<Vector3>();
			List<ushort> inds = new List<ushort>();

			int y_count = tesselation / (hemisphere ? 2 : 1);
			for (int y = 0; y <= y_count; y++)
			{
				float ay = y / tes * (float)Math.PI;
				int div = (int)(tesselation * 2 * (float)Math.Sin(ay)) + 1;

				for (int x = 0; x <= div; x++)
				{
					float ax = x / (float)div * (float)Math.PI * 2.0f;

					float s = (float)Math.Sin(ay);
					Vector3 norm = new Vector3((float)Math.Cos(ax) * s, (float)Math.Sin(ax) * s, (float)Math.Cos(ay));

					if (storePositionOnly)
						vertsPos.Add(norm * size);
					else
						verts.Add(new VertexPositionNormalTexture(norm * size, norm, new Vector2(ax / (float)Math.PI * 0.5f, ay / (float)Math.PI)));
				}
				
				if (prevCount != -1)
				{
					int p = 0, c = 0;
					while (p != prevCount || c != div)
					{
						if (p / (float)prevCount > c / (float)div)
						{
							inds.Add((ushort)(c % div + startIndex));
							inds.Add((ushort)(p % prevCount + prevStartIndex));
							inds.Add((ushort)((++c) % div + startIndex));
						}
						else
						{
							inds.Add((ushort)(c%div + startIndex));
							inds.Add((ushort)(p % prevCount + prevStartIndex));
							inds.Add((ushort)((++p) % prevCount + prevStartIndex));
						}
					}
				}

				prevCount = div;
				prevStartIndex = startIndex;
				startIndex += div + 1;
			}

			if (storePositionOnly)
				this.verts = new Vertices<Vector3>(vertsPos);
			else
				this.verts = new Vertices<VertexPositionNormalTexture>(verts);
			this.inds = new Indices<ushort>(inds);
		}
Example #27
0
        /// <summary>
        /// Create spherical geometry
        /// </summary>
        /// <param name="size">Size of the sphere</param>
        /// <param name="tesselation">Tesselation of the sphere. Approx number of triangles will be tesselation*tesselation</param>
        /// <param name="storePositionOnly">Store only position, no normals or texture coordinates</param>
        /// <param name="hemisphere">Generate a hemisphere</param>
        /// <param name="sizeToInternalSphere">Expand the sphere to compensate for smaller internal size caused by low tesselation</param>
        public Sphere(Vector3 size, int tesselation, bool storePositionOnly, bool hemisphere, bool sizeToInternalSphere)
        {
            if (tesselation <= 1)
            {
                throw new ArgumentException("tesselation is too small");
            }
            this.radius = Math.Max(Math.Abs(size.X), Math.Max(Math.Abs(size.Y), Math.Abs(size.Z)));

            //if true, then a sphere of 'size' should not intersect if placed within this mesh.
            //since the resolution isn't limitless, the flat surfaces will make the internal size slightly smaller.
            //so expand to compensate
            if (sizeToInternalSphere)
            {
                size /= (float)Math.Cos(Math.PI / tesselation);
            }
            geometryRadius = Math.Max(Math.Abs(size.X), Math.Max(Math.Abs(size.Y), Math.Abs(size.Z)));

            float tes            = tesselation;
            int   prevCount      = -1;
            int   startIndex     = 0;
            int   prevStartIndex = 0;
            List <VertexPositionNormalTexture> verts = new List <VertexPositionNormalTexture>();
            List <Vector3> vertsPos = new List <Vector3>();
            List <ushort>  inds     = new List <ushort>();

            int y_count = tesselation / (hemisphere ? 2 : 1);

            for (int y = 0; y <= y_count; y++)
            {
                float ay  = y / tes * (float)Math.PI;
                int   div = (int)(tesselation * 2 * (float)Math.Sin(ay)) + 1;

                for (int x = 0; x < div; x++)
                {
                    float ax = x / (float)div * (float)Math.PI * 2.0f;

                    float   s    = (float)Math.Sin(ay);
                    Vector3 norm = new Vector3((float)Math.Cos(ax) * s, (float)Math.Sin(ax) * s, (float)Math.Cos(ay));

                    if (storePositionOnly)
                    {
                        vertsPos.Add(norm * size);
                    }
                    else
                    {
                        verts.Add(new VertexPositionNormalTexture(norm * size, norm, new Vector2(ax / (float)Math.PI * 0.5f, ay / (float)Math.PI)));
                    }
                }

                if (prevCount != -1)
                {
                    int p = 0, c = 0;
                    while (p != prevCount || c != div)
                    {
                        if (p / (float)prevCount > c / (float)div)
                        {
                            inds.Add((ushort)(c % div + startIndex));
                            inds.Add((ushort)(p % prevCount + prevStartIndex));
                            inds.Add((ushort)((++c) % div + startIndex));
                        }
                        else
                        {
                            inds.Add((ushort)(c % div + startIndex));
                            inds.Add((ushort)(p % prevCount + prevStartIndex));
                            inds.Add((ushort)((++p) % prevCount + prevStartIndex));
                        }
                    }
                }

                prevCount      = div;
                prevStartIndex = startIndex;
                startIndex    += div;
            }

            if (storePositionOnly)
            {
                this.verts = new Vertices <Vector3>(vertsPos);
            }
            else
            {
                this.verts = new Vertices <VertexPositionNormalTexture>(verts);
            }
            this.inds = new Indices <ushort>(inds);
        }
		/// <summary>
		/// Get global vertices/indices for drawing billboards
		/// </summary>
		/// <param name="state"></param>
		/// <param name="vertices"></param>
		/// <param name="indices"></param>
		public static void GenerateBillboardVertices(DrawState state, ref IVertices vertices, ref IIndices indices)
		{
			if (vertices != null)
				return;

			vertices = state.Application.UserValues[verticesID] as IVertices;
			indices = state.Application.UserValues[indicesID] as IIndices;

			if (vertices != null)
				return;

			//8192 will be approx 512kb (however there is only one copy for the entire app)
#if XBOX360
			int maxVerts = 8192;
#else
			int maxVerts = ParticleSystem.SystemSupportsGpuParticles ? 8192 : 512;
#endif

			Vector4[] vertexData = new Vector4[maxVerts * 4];
			ushort[] indexData = new ushort[maxVerts * 6];

			int v = 0;
			int i = 0;
			for (int n = 0; n < maxVerts; n++)
			{
				vertexData[v++] = new Vector4(n, -1,  1, 0);
				vertexData[v++] = new Vector4(n,  1,  1, 0);
				vertexData[v++] = new Vector4(n,  1, -1, 0);
				vertexData[v++] = new Vector4(n, -1, -1, 0);

				indexData[i++] = (ushort)(n * 4 + 0);
				indexData[i++] = (ushort)(n * 4 + 1);
				indexData[i++] = (ushort)(n * 4 + 2);

				indexData[i++] = (ushort)(n * 4 + 0);
				indexData[i++] = (ushort)(n * 4 + 2);
				indexData[i++] = (ushort)(n * 4 + 3);
			}

			vertices = new Vertices<Vector4>(vertexData);
			indices = new Indices<ushort>(indexData);

			state.Application.UserValues[verticesID] = vertices;
			state.Application.UserValues[indicesID] = indices;
		}
		public GroundDisk(ContentRegister content, MaterialLightCollection lights, float radius)
		{
			this.radius = radius;

			int vertexCount = 256;
			var indices = new List<int>();

			//create the vertices. Note the DiskVertex() constructor takes an angle/size
			var verts = new DiskVertex[vertexCount];

			for (int i = 0; i < vertexCount; i++)
			{
				verts[i] = new DiskVertex((i / (float)(vertexCount - 1)) * MathHelper.TwoPi, radius, 0.05f);
				
				if (i != 0)	//add the tirangle indices
				{
					indices.Add(0);
					indices.Add(i - 1);
					indices.Add(i);
				}
			}

			//create the vertex buffer
			this.vertices = new Vertices<DiskVertex>(verts);
			this.indices = new Indices<int>(indices);


			//create the custom material for this geometry
			//the light collection has been passed into the constructor, although it
			//could easily be changed later (by changing material.Lights)
			this.Material = new MaterialShader(lights);
			
			//give the disk really bright specular for effect
			Material.SpecularColour = new Vector3(1,1,1);
			Material.DiffuseColour = new Vector3(0.6f, 0.6f, 0.6f);
			Material.SpecularPower = 64;

			//setup the texture samples to use high quality anisotropic filtering
			//the textures are assigned in LoadContent
			Material.Textures = new MaterialTextures();
			Material.Textures.TextureMapSampler = TextureSamplerState.AnisotropicHighFiltering;
			Material.Textures.NormalMapSampler = TextureSamplerState.AnisotropicLowFiltering;

			//load the textures for this material
			content.Add(this);
		}
		/// <summary>Generates a vertex buffer used for drawing lines in GPU or CPU batches</summary>
		public static void GenerateLinesVertices(DrawState state, ref IVertices vertices)
		{
			if (vertices != null)
				return;

			vertices = state.Application.UserValues[verticesID] as IVertices;

			if (vertices != null)
				return;

			//4096 will be approx 256kb (however there is only one copy for the entire app)
#if XBOX360
			int maxVerts = 4096;
#else
			int maxVerts = ParticleSystem.SystemSupportsGpuParticles ? 4096 : 512;
#endif

			Vector2[] vertexData = new Vector2[maxVerts * 2];

			int v = 0;
			for (int n = 0; n < maxVerts; n++)
			{
				vertexData[v++] = new Vector2(n, -1);
				vertexData[v++] = new Vector2(n, 1);
			}

			vertices = Vertices<Vector2>.CreateSingleElementVertices(vertexData, VertexElementUsage.Position, 0);

			state.Application.UserValues[verticesID] = vertices;
		}
Example #31
0
		/// <summary>
		/// 
		/// </summary>
		/// <param name="size"></param>
		/// <param name="tesselation"></param>
		/// <param name="positionOnly">vertex data will only store position</param>
		/// <param name="sizeToInternalCone">expand the cone geometry outwards so it encoses the desired size</param>
		public Cone(Vector3 size, int tesselation, bool positionOnly, bool sizeToInternalCone)
		{
			if (tesselation <= 2)
				throw new ArgumentException("tesselation is too small");
			if (size.Z == 0)
				throw new ArgumentException("size.Z == 0");

			this.radius = 0;
			//this.radius = Math.Max(Math.Abs(size.X), Math.Max(Math.Abs(size.Y), Math.Abs(size.Z)));

			//if true, then a cone of 'size' should not intersect if placed within this mesh.
			//since the resolution isn't limitless, the flat surfaces will make the internal size slightly smaller.
			//so expand to compensate
			if (sizeToInternalCone)
			{
				float s = 1.0f/(float)Math.Cos(Math.PI / tesselation);
				size.X *= s;
				size.Y *= s;
			}
			geometryRadius = Math.Max(Math.Abs(size.X), Math.Max(Math.Abs(size.Y), Math.Abs(size.Z)));

			float tes = tesselation;
			int prevCount = -1;
			int startIndex = 0;
			int prevStartIndex = 0;
			List<VertexPositionNormalTexture> verts = new List<VertexPositionNormalTexture>();
			List<Vector3> vertsPos = new List<Vector3>();
			List<ushort> inds = new List<ushort>();

			if (positionOnly)
				vertsPos.Add(Vector3.Zero);
			else
				verts.Add(new VertexPositionNormalTexture(Vector3.Zero, Vector3.Zero, new Vector2(0.5f, 0.5f)));

			int y_count = tesselation;
			for (int y = 0; y < y_count; y++)
			{
				float ay = y / tes * (float)Math.PI * 2.0f;
				int div = (int)(tesselation * 2 * (float)Math.Sin(ay)) + 1;


				Vector3 norm = new Vector3((float)Math.Cos(ay), (float)Math.Sin(ay), 1);
				Vector3 pos = norm * size;
				this.radius = Math.Max(this.radius, pos.LengthSquared());
				Vector2 tex = new Vector2(norm.X * 0.5f + 0.5f, norm.Y * 0.5f + 0.5f);

				if (positionOnly)
					vertsPos.Add(pos);
				else
					verts.Add(new VertexPositionNormalTexture(pos, new Vector3(0, 0, Math.Sign(size.Z)), tex));

				norm.X *= -size.Z/size.X;
				norm.Y *= -size.Z/size.Y;
				norm.Normalize();

				if (!positionOnly)
					verts.Add(new VertexPositionNormalTexture(pos, -norm, tex));

				if (positionOnly)
				{
					inds.Add(0);
					inds.Add((ushort)(y + 1));
					inds.Add((ushort)((y + 1) % y_count + 1));

					if (y != 0 && y != y_count - 1)
					{
						inds.Add(1);
						inds.Add((ushort)((y + 1) % y_count + 1));
						inds.Add((ushort)(y + 1));
					}
				}
				else
				{
					inds.Add(0);
					inds.Add((ushort)(y * 2 + 2));
					inds.Add((ushort)(((y + 1) % y_count) * 2 + 2));

					if (y != 0 && y != y_count-1)
					{
						inds.Add(1);
						inds.Add((ushort)(((y + 1) % y_count) * 2 + 1));
						inds.Add((ushort)(y*2+1));
					}
				}

				prevCount = div;
				prevStartIndex = startIndex;
				startIndex += div;
			}

			if (this.radius != 0)
				this.radius = (float)Math.Sqrt(this.radius);

			if (positionOnly)
				this.verts = new Vertices<Vector3>(vertsPos);
			else
				this.verts = new Vertices<VertexPositionNormalTexture>(verts);
			this.inds = new Indices<ushort>(inds);
		}
Example #32
0
 public bool IsNeighbour(IVertices other)
 {
     return(Vertices.Intersect(other.Vertices).Count() >= 2);
 }
Example #33
0
        /// <summary></summary>
        /// <param name="state"></param>
        /// <param name="maskOnly"></param>
        protected override sealed void BindShader(DrawState state, bool maskOnly)
        {
            if (this.vertices == null)
            {
                this.vertices = state.UserValues[GetType().FullName + ".vertices"] as IVertices;
                this.indices  = state.UserValues[GetType().FullName + ".indices"] as Indices <ushort>;

                this.verticesSI = state.UserValues[GetType().FullName + ".verticesSI"] as IVertices;
                this.indicesSI  = state.UserValues[GetType().FullName + ".indicesSI"] as Indices <ushort>;

                if (this.vertices == null)
                {
                    //still null, create the global vertices
                    this.vertices = new Vertices <Vector4>(
                        new Vector4(0, 0, 0, 1),
                        new Vector4(1, 0, 0, 1),
                        new Vector4(1, 1, 0, 1),
                        new Vector4(0, 1, 0, 1));

                    this.indices = new Indices <ushort>(0, 2, 1, 0, 3, 2);

                    //shader instancing..
                    List <InstanceVertex> verts = new List <InstanceVertex>();
                    List <ushort>         inds  = new List <ushort>();

                    for (int i = 0; i < NonInstancingRenderCount; i++)
                    {
                        verts.Add(new InstanceVertex(new Vector3(0, 0, 0), (float)i));
                        verts.Add(new InstanceVertex(new Vector3(1, 0, 0), (float)i));
                        verts.Add(new InstanceVertex(new Vector3(1, 1, 0), (float)i));
                        verts.Add(new InstanceVertex(new Vector3(0, 1, 0), (float)i));

                        inds.Add((ushort)(0 + i * 4));
                        inds.Add((ushort)(2 + i * 4));
                        inds.Add((ushort)(1 + i * 4));
                        inds.Add((ushort)(0 + i * 4));
                        inds.Add((ushort)(3 + i * 4));
                        inds.Add((ushort)(2 + i * 4));
                    }

                    this.verticesSI = new Vertices <InstanceVertex>(verts.ToArray());
                    this.indicesSI  = new Indices <ushort>(inds.ToArray());

                    state.UserValues[GetType().FullName + ".vertices"]   = vertices;
                    state.UserValues[GetType().FullName + ".indices"]    = indices;
                    state.UserValues[GetType().FullName + ".verticesSI"] = verticesSI;
                    state.UserValues[GetType().FullName + ".indicesSI"]  = indicesSI;
                }
            }

            if (state.SupportsHardwareInstancing && instanceCount > HardwareInstancingMinimum)
            {
                Graphics2D.InstancingSprite shader = state.GetShader <Graphics2D.InstancingSprite>();
                Matrix world;
                state.GetWorldMatrix(out world);
                shader.SetSpriteWorldMatrix(ref world);
                shader.CustomTexture = texture ?? Xen.Ex.Material.WhiteTexture.GetTexture(state);
                shader.Bind(state);
            }
            else
            {
                Graphics2D.NonInstancingSprite shader = state.GetShader <Graphics2D.NonInstancingSprite>();
                shader.CustomTexture = texture ?? Xen.Ex.Material.WhiteTexture.GetTexture(state);
                shader.Bind(state);
            }
        }
		protected override void DrawElement(DrawState state)
		{
			if (graph == null)
			{
				graph = state.Application.UserValues[graphID] as IVertices;

				if (graph == null)
				{
					float[] graphValues = new float[MaxGraphSamples];
					for (int i = 0; i < MaxGraphSamples; i++)
						graphValues[i] = (float)i;

					this.graph = Vertices<float>.CreateSingleElementVertices(graphValues, VertexElementUsage.Position, 0);
					state.Application.UserValues[graphID] = this.graph;
				}
			}

			graph.Draw(state, null, PrimitiveType.LineStrip, this.values.Length - 1,0,0);
		}
Example #35
0
 /// <summary>
 /// Create a Geometry object.
 /// </summary>
 /// <param name="device">The graphics device to create the geometry on.</param>
 /// <param name="primitiveType">The type of primitive used to draw the geometry.</param>
 /// <param name="vertices">The vertices of the geometry.</param>
 /// <param name="indices">The indices of the geometry.</param>
 public Geometry(GraphicsDevice device, PrimitiveType primitiveType, IVertices vertices, int[] indices)
     : this(device, primitiveType, vertices)
 {
     XiHelper.ArgumentNullCheck(device, vertices, indices);
     indexCount = indices.Length;
     indexBuffer = new IndexBuffer(device, typeof(int), indices.Length, BufferUsage.None);
     indexBuffer.SetData<int>(indices);
     primitiveCount = primitiveType.GetPrimitiveCount(indices.Length);
 }
		/// <summary></summary>
		/// <param name="state"></param>
		/// <param name="maskOnly"></param>
		protected override sealed IShader BindShader(DrawState state, bool maskOnly)
		{
			if (this.vertices == null)
			{
				this.vertices = state.Application.UserValues[GetType().FullName + ".vertices"] as IVertices;
				this.indices = state.Application.UserValues[GetType().FullName + ".indices"] as Indices<ushort>;

				this.verticesSI = state.Application.UserValues[GetType().FullName + ".verticesSI"] as IVertices;
				this.indicesSI = state.Application.UserValues[GetType().FullName + ".indicesSI"] as Indices<ushort>;

				if (this.vertices == null)
				{
					//still null, create the global vertices
					this.vertices = new Vertices<Vector4>(
						new Vector4(0, 0, 0, 1),
						new Vector4(1, 0, 0, 1),
						new Vector4(1, 1, 0, 1),
						new Vector4(0, 1, 0, 1));

					this.indices = new Indices<ushort>(0, 2, 1, 0, 3, 2);

					//shader instancing..
					List<InstanceVertex> verts = new List<InstanceVertex>();
					List<ushort> inds = new List<ushort>();

					for (int i = 0; i < NonInstancingRenderCount; i++)
					{
						verts.Add(new InstanceVertex(new Vector3(0, 0, 0), (float)i));
						verts.Add(new InstanceVertex(new Vector3(1, 0, 0), (float)i));
						verts.Add(new InstanceVertex(new Vector3(1, 1, 0), (float)i));
						verts.Add(new InstanceVertex(new Vector3(0, 1, 0), (float)i));

						inds.Add((ushort)(0 + i * 4));
						inds.Add((ushort)(2 + i * 4));
						inds.Add((ushort)(1 + i * 4));
						inds.Add((ushort)(0 + i * 4));
						inds.Add((ushort)(3 + i * 4));
						inds.Add((ushort)(2 + i * 4));
					}

					this.verticesSI = new Vertices<InstanceVertex>(verts.ToArray());
					this.indicesSI = new Indices<ushort>(inds.ToArray());

					state.Application.UserValues[GetType().FullName + ".vertices"] = vertices;
					state.Application.UserValues[GetType().FullName + ".indices"] = indices;
					state.Application.UserValues[GetType().FullName + ".verticesSI"] = verticesSI;
					state.Application.UserValues[GetType().FullName + ".indicesSI"] = indicesSI;
				}
			}

			if (state.Properties.SupportsHardwareInstancing && instanceCount > HardwareInstancingMinimum)
			{
				Graphics2D.InstancingSprite shader = state.GetShader<Graphics2D.InstancingSprite>();
				Matrix world;
				state.WorldMatrix.GetMatrix(out world);
				shader.SetSpriteWorldMatrix(ref world);
				shader.CustomTexture = texture ?? state.Properties.WhiteTexture;
				return shader;
			}
			else
			{
				Graphics2D.NonInstancingSprite shader = state.GetShader<Graphics2D.NonInstancingSprite>();

				shader.CustomTexture = texture ?? state.Properties.WhiteTexture;
				return shader;
			}
		}
		public GroundLightDisk(Vector3 position)
		{
			Matrix.CreateTranslation(ref position, out worldMatrix);

			const int vertCount = 32;
			//make a ground plane using two triangles
			//this is a bit nasty as the vertex buffer is recreated for each fire
			var verts = new VertexPositionColor[vertCount+2];
			var indices = new List<int>();

			//create vertices in a circle. The first vertex is in the centre. (Triangle Fan)
			verts[0] = new VertexPositionColor(Vector3.Zero, new Color(64,40,20));
			for (int i = 0; i <= vertCount; i++)
			{
				float angle = ((float)i / (float)vertCount) * MathHelper.TwoPi;
				verts[i + 1] = new VertexPositionColor(new Vector3((float)Math.Sin(angle) * 3, 0, (float)Math.Cos(angle) * 3), Color.Black);
				if (i > 0)
				{
					indices.Add(0);
					indices.Add(i);
					indices.Add(i + 1);
				}
			}
			this.indices = new Indices<int>(indices);
			this.vertices = new Vertices<VertexPositionColor>(verts);
		}
Example #38
0
        /// <summary></summary>
        /// <param name="size"></param>
        /// <param name="maxAngle"></param>
        /// <param name="tesselation"></param>
        /// <param name="positionOnly"></param>
        /// <param name="sizeToInternalSphere"></param>
        public SphericalCone(Vector3 size, float maxAngle, int tesselation, bool positionOnly, bool sizeToInternalSphere)
        {
            if (tesselation <= 1)
            {
                throw new ArgumentException("tesselation is too small");
            }
            this.radius = Math.Max(Math.Abs(size.X), Math.Max(Math.Abs(size.Y), Math.Abs(size.Z)));

            if (maxAngle > MathHelper.TwoPi)
            {
                throw new ArgumentException();
            }

            //if true, then a sphere of 'size' should not intersect if placed within this mesh.
            //since the resolution isn't limitless, the flat surfaces will make the internal size slightly smaller.
            //so expand to compensate
            if (sizeToInternalSphere)
            {
                size /= (float)Math.Cos(Math.PI / tesselation);
            }
            geometryRadius = Math.Max(Math.Abs(size.X), Math.Max(Math.Abs(size.Y), Math.Abs(size.Z)));

            float tes            = tesselation;
            int   prevCount      = -1;
            int   startIndex     = 0;
            int   prevStartIndex = 0;
            List <VertexPositionNormalTexture> verts = new List <VertexPositionNormalTexture>();
            List <Vector3> vertsPos = new List <Vector3>();
            List <ushort>  inds     = new List <ushort>();

            float ay;
            int   div;

            int y_count = (int)Math.Ceiling(tesselation * maxAngle / (Math.PI * 2));

            if (y_count > tesselation)
            {
                y_count = tesselation;
            }

            if (sizeToInternalSphere)
            {
                maxAngle /= (float)Math.Cos(Math.PI / tesselation);
            }

            for (int y = 0; y <= y_count; y++)
            {
                ay = y / tes * (float)Math.PI;

                if (ay > maxAngle * 0.5f)
                {
                    ay = maxAngle * 0.5f;
                }

                div = (int)(tesselation * 2 * (float)Math.Sin(ay)) + 1;

                for (int x = 0; x < div; x++)
                {
                    float ax = x / (float)div * (float)Math.PI * 2.0f;

                    float   s    = (float)Math.Sin(ay);
                    Vector3 norm = new Vector3((float)Math.Cos(ax) * s, (float)Math.Sin(ax) * s, (float)Math.Cos(ay));

                    if (positionOnly)
                    {
                        vertsPos.Add(norm * size);
                    }
                    else
                    {
                        verts.Add(new VertexPositionNormalTexture(norm * size, norm, new Vector2(ax / (float)Math.PI * 0.5f, ay / (float)Math.PI)));
                    }
                }

                if (prevCount != -1)
                {
                    int p = 0, c = 0;
                    while (p != prevCount || c != div)
                    {
                        if (p / (float)prevCount > c / (float)div)
                        {
                            inds.Add((ushort)(c % div + startIndex));
                            inds.Add((ushort)(p % prevCount + prevStartIndex));
                            inds.Add((ushort)((++c) % div + startIndex));
                        }
                        else
                        {
                            inds.Add((ushort)(c % div + startIndex));
                            inds.Add((ushort)(p % prevCount + prevStartIndex));
                            inds.Add((ushort)((++p) % prevCount + prevStartIndex));
                        }
                    }
                }

                prevCount      = div;
                prevStartIndex = startIndex;
                startIndex    += div;
            }

            //not a sphere
            if (y_count != tesselation)
            {
                ay = maxAngle * 0.5f;

                div = (int)(tesselation * 2 * (float)Math.Sin(ay)) + 1;
                int edgeBaseIndex = positionOnly ? vertsPos.Count : verts.Count;

                if (positionOnly)
                {
                    vertsPos.Add(Vector3.Zero);
                }
                else
                {
                    verts.Add(new VertexPositionNormalTexture(Vector3.Zero, Vector3.Zero, new Vector2(0.0f, 0.0f)));
                }

                for (int x = 0; x < div; x++)
                {
                    float ax = x / (float)div * (float)Math.PI * 2.0f;

                    float   s    = (float)Math.Sin(ay);
                    Vector3 norm = new Vector3((float)Math.Cos(ax) * (float)Math.Cos(ay), (float)Math.Sin(ax) * (float)Math.Cos(ay), -(float)Math.Sin(ay));
                    Vector3 pos  = new Vector3((float)Math.Cos(ax) * s, (float)Math.Sin(ax) * s, (float)Math.Cos(ay)) * size;



                    if (positionOnly)
                    {
                        vertsPos.Add(pos);
                    }
                    else
                    {
                        verts.Add(new VertexPositionNormalTexture(pos, norm, new Vector2(ax / (float)Math.PI * 0.5f, ay / (float)Math.PI)));
                    }

                    inds.Add((ushort)(edgeBaseIndex));
                    inds.Add((ushort)(edgeBaseIndex + 1 + x));
                    inds.Add((ushort)(edgeBaseIndex + 1 + (x + 1) % div));
                }
            }



            if (positionOnly)
            {
                this.verts = new Vertices <Vector3>(vertsPos);
            }
            else
            {
                this.verts = new Vertices <VertexPositionNormalTexture>(verts);
            }
            this.inds = new Indices <ushort>(inds);
        }
		//
		// NOTE:
		//
		// ----------------------
		//  New to Xen 1.6.3:
		// ----------------------
		//
		// The DrawState object has had the methods 'DrawDynamicVertices<>' and 'DrawDynamicIndexedVertices<>' added.
		// These methods wrap XNA DrawUserPrimitives and DrawUserIndexedPrimitives. Like existing Vertices<> objects,
		// these methods take care of the VertexDeclaration and render state for your.
		//
		// For volatile dynamic data (data that changes every frame) these methods are just as efficient as the
		// method demonstrated in this example. In some cases, it can be simpler to use this method too.
		//
		// These methods do not require a Vertices<> or Indices<> object, as they copy the entire vertex/index array
		// every frame when you make the draw call.
		//
		// For dynamic data that may not change every frame, using the method in this example is recommended.
		//

		//setup and create the vertices/indices
		public DynamicQuadGeometry()
		{
			//create the array of custom vertices, to form a quad
			this.vertexData = new CustomVertex[4]
			{
				new CustomVertex(new Vector3(-1,-1,0), Vector3.UnitZ), // bottom left
				new CustomVertex(new Vector3(-1, 1,0), Vector3.UnitZ), // top left
				new CustomVertex(new Vector3( 1,-1,0), Vector3.UnitZ), // bottom right
				new CustomVertex(new Vector3( 1, 1,0), Vector3.UnitZ), // top right
			};

			//create the buffers
			this.vertices = new Vertices<CustomVertex>(vertexData);

			this.indices = new Indices<ushort>(0, 1, 2, 1, 3, 2);		//this is a shortcut using params[] supporting constructor

			//NEW CODE
			//Set the resource usage of the vertices to Dynamic
			//This can only be set before the vertices are first used
			this.vertices.ResourceUsage = ResourceUsage.Dynamic;
		}
		private void GenCubeVS(DrawState state)
		{
			if (cubeVS != null) return;
			cubeVS = state.Application.UserValues[cubeVSid] as IVertices;
			if (cubeVS != null) return;

			//cube outlines, between 0,0,0 and 1,1,1
			cubeVS = new Vertices<Vector3>(
				new Vector3(0,0,0),new Vector3(1,0,0),new Vector3(0,1,0),new Vector3(1,1,0),
				new Vector3(0,0,1),new Vector3(1,0,1),new Vector3(0,1,1),new Vector3(1,1,1),

				new Vector3(0,0,0),new Vector3(0,1,0),new Vector3(1,0,0),new Vector3(1,1,0),
				new Vector3(0,0,1),new Vector3(0,1,1),new Vector3(1,0,1),new Vector3(1,1,1),
				
				new Vector3(0,0,0),new Vector3(0,0,1),new Vector3(1,0,0),new Vector3(1,0,1),				
				new Vector3(0,1,0),new Vector3(0,1,1),new Vector3(1,1,0),new Vector3(1,1,1)
			);
			state.Application.UserValues[cubeVSid] = cubeVS;
		}
		/// <summary></summary>
		/// <param name="size"></param>
		/// <param name="maxAngle"></param>
		/// <param name="tesselation"></param>
		/// <param name="positionOnly"></param>
		/// <param name="sizeToInternalSphere"></param>
		public SphericalCone(Vector3 size, float maxAngle, int tesselation, bool positionOnly, bool sizeToInternalSphere)
		{
			if (tesselation <= 1)
				throw new ArgumentException("tesselation is too small");
			this.radius = Math.Max(Math.Abs(size.X),Math.Max(Math.Abs(size.Y),Math.Abs(size.Z)));

			if (maxAngle > MathHelper.TwoPi)
				throw new ArgumentException();

			//if true, then a sphere of 'size' should not intersect if placed within this mesh.
			//since the resolution isn't limitless, the flat surfaces will make the internal size slightly smaller.
			//so expand to compensate
			if (sizeToInternalSphere)
			{
				size /= (float)Math.Cos(Math.PI / tesselation);
			}
			geometryRadius = Math.Max(Math.Abs(size.X), Math.Max(Math.Abs(size.Y), Math.Abs(size.Z)));

			float tes = tesselation;
			int prevCount = -1;
			int startIndex = 0;
			int prevStartIndex = 0;
			List<VertexPositionNormalTexture> verts = new List<VertexPositionNormalTexture>();
			List<Vector3> vertsPos = new List<Vector3>();
			List<ushort> inds = new List<ushort>();

			float ay;
			int div;

			int y_count = (int)Math.Ceiling(tesselation * maxAngle / (Math.PI * 2));
			if (y_count > tesselation)
				y_count = tesselation;

			if (sizeToInternalSphere)
			{
				maxAngle /= (float)Math.Cos(Math.PI / tesselation);
			}

			for (int y = 0; y <= y_count; y++)
			{
				ay = y / tes * (float)Math.PI;

				if (ay > maxAngle * 0.5f)
					ay = maxAngle * 0.5f;

				div = (int)(tesselation * 2 * (float)Math.Sin(ay)) + 1;

				for (int x = 0; x < div; x++)
				{
					float ax = x / (float)div * (float)Math.PI * 2.0f;

					float s = (float)Math.Sin(ay);
					Vector3 norm = new Vector3((float)Math.Cos(ax) * s, (float)Math.Sin(ax) * s, (float)Math.Cos(ay));

					if (positionOnly)
						vertsPos.Add(norm * size);
					else
						verts.Add(new VertexPositionNormalTexture(norm * size, norm, new Vector2(ax / (float)Math.PI * 0.5f, ay / (float)Math.PI)));
				}
				
				if (prevCount != -1)
				{
					int p = 0, c = 0;
					while (p != prevCount || c != div)
					{
						if (p / (float)prevCount > c / (float)div)
						{
							inds.Add((ushort)(c % div + startIndex));
							inds.Add((ushort)(p % prevCount + prevStartIndex));
							inds.Add((ushort)((++c) % div + startIndex));
						}
						else
						{
							inds.Add((ushort)(c%div + startIndex));
							inds.Add((ushort)(p % prevCount + prevStartIndex));
							inds.Add((ushort)((++p) % prevCount + prevStartIndex));
						}
					}
				}

				prevCount = div;
				prevStartIndex = startIndex;
				startIndex += div;
			}

			//not a sphere
			if (y_count != tesselation)
			{
				ay = maxAngle * 0.5f;

				div = (int)(tesselation * 2 * (float)Math.Sin(ay)) + 1;
				int edgeBaseIndex = positionOnly ? vertsPos.Count : verts.Count;

				if (positionOnly)
					vertsPos.Add(Vector3.Zero);
				else
					verts.Add(new VertexPositionNormalTexture(Vector3.Zero, Vector3.Zero, new Vector2(0.0f, 0.0f)));

				for (int x = 0; x < div; x++)
				{
					float ax = x / (float)div * (float)Math.PI * 2.0f;

					float s = (float)Math.Sin(ay);
					Vector3 norm = new Vector3((float)Math.Cos(ax) * (float)Math.Cos(ay), (float)Math.Sin(ax) * (float)Math.Cos(ay), -(float)Math.Sin(ay));
					Vector3 pos = new Vector3((float)Math.Cos(ax) * s, (float)Math.Sin(ax) * s, (float)Math.Cos(ay)) * size;



					if (positionOnly)
						vertsPos.Add(pos);
					else
						verts.Add(new VertexPositionNormalTexture(pos, norm, new Vector2(ax / (float)Math.PI * 0.5f, ay / (float)Math.PI)));

					inds.Add((ushort)(edgeBaseIndex));
					inds.Add((ushort)(edgeBaseIndex + 1 + x));
					inds.Add((ushort)(edgeBaseIndex + 1 + (x + 1) % div));
				}
			}



			if (positionOnly)
				this.verts = new Vertices<Vector3>(vertsPos);
			else
				this.verts = new Vertices<VertexPositionNormalTexture>(verts);
			this.inds = new Indices<ushort>(inds);
		}
    public static Vector3 CalculateNormal(this IVertices source)
    {
        var dir = Vector3.Cross(source.Vertices[1] - source.Vertices[0], source.Vertices[2] - source.Vertices[0]);

        return(Vector3.Normalize(dir));
    }