/// <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 ); }
/// <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 ); }
/// <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; }
// // 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; }
//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); }
//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); }
/// <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; }
/// <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); }
public static IIndices create(IIndices indices) { throw new NotImplementedException(); }
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); }
public StructureOfContractions(Tensor[] data, int differentIndicesCount, IIndices freeIndices) { //Names (names with type, see IndicesUtils.getNameWithType() ) of all indices in this multiplication //It will be used as index name -> index index [0,1,2,3...] mapping int[] upperIndices = new int[differentIndicesCount], lowerIndices = new int[differentIndicesCount]; //This is sorage for intermediate information about indices, used in the algorithm (see below) //Structure: // ulong[] upperInfo = new ulong[differentIndicesCount], lowerInfo = new ulong[differentIndicesCount]; //This is for generalization of algorithm //indices[0] == lowerIndices //indices[1] == lowerIndices int[][] indices = { lowerIndices, upperIndices }; //This is for generalization of algorithm too //info[0] == lowerInfo //info[1] == lowerInfo ulong[][] info = { lowerInfo, upperInfo }; //Pointers for lower and upper indices, used in algorithm //pointer[0] - pointer to lower //pointer[1] - pointer to upper int[] pointer = new int[2]; //Allocating array for results, one contraction for each tensor contractions = new long[data.Length][]; //There is one dummy tensor with index -1, it represents fake //tensor contracting with whole Product to leave no contracting indices. //So, all "conractions" with this dummy "contraction" looks like a scalar //product. (sorry for English) freeContractions = new long[freeIndices.Size()]; uint state; uint index; uint i; //Processing free indices = creating contractions for dummy tensor for (i = 0; i < freeIndices.Size(); ++i) { index = freeIndices[i]; //Inverse state (because it is state of index at (??) dummy tensor, //contracted with this free index) state = 1 - IndicesUtils.getStateInt(index); //Important: info[state][pointer[state]] = dummyTensorInfo; indices[state][pointer[state]++] = IndicesUtils.GetNameWithType(index); } int tensorIndex; for (tensorIndex = 0; tensorIndex < data.Length; ++tensorIndex) { //Main algorithm IIndices tInds = data[tensorIndex].Indices; short[] diffIds = tInds.GetDiffIds(); //FUTURE move to other place if (tInds.Size() >= 0x10000) { throw new InvalidOperationException("Too many indices!!! max count = 2^16"); } for (uint j = 0; j < tInds.Size(); ++j) { index = tInds[j]; state = IndicesUtils.getStateInt(index); info[state][pointer[state]] = packToLong(tensorIndex, diffIds[j], j); indices[state][pointer[state]++] = IndicesUtils.GetNameWithType(index); } //Result allocation contractions[tensorIndex] = new long[tInds.Size()]; } //Here we can use unstable sorting algorithm (all indices are different) ArraysUtils.quickSort(indices[0], info[0].Select(u => (int)u).ToArray()); ArraysUtils.quickSort(indices[1], info[1].Select(u => (int)u).ToArray()); //Calculating connected components var infoTensorIndicesFrom = infoToTensorIndices(lowerInfo); var infoTensorIndicesTo = infoToTensorIndices(upperInfo); uint shift = 0; uint last = 0; for (i = 0; i < infoTensorIndicesFrom.Length; ++i) { if (infoTensorIndicesFrom[i] == -1 || infoTensorIndicesTo[i] == -1) { Array.Copy(infoTensorIndicesFrom, last, infoTensorIndicesFrom, last - shift, i - last); Array.Copy(infoTensorIndicesTo, last, infoTensorIndicesTo, last - shift, i - last); last = i + 1; ++shift; } } Array.Copy(infoTensorIndicesFrom, last, infoTensorIndicesFrom, last - shift, i - last); Array.Copy(infoTensorIndicesTo, last, infoTensorIndicesTo, last - shift, i - last); infoTensorIndicesFrom = Arrays.copyOf(infoTensorIndicesFrom, (int)(infoTensorIndicesFrom.Length - shift)); infoTensorIndicesTo = Arrays.copyOf(infoTensorIndicesTo, (int)(infoTensorIndicesTo.Length - shift)); int[] components = GraphUtils.CalculateConnectedComponents(infoTensorIndicesFrom, infoTensorIndicesTo, data.Length); componentCount = components[components.Length - 1]; this.components = Arrays.copyOfRange(components, 0, components.Length - 1); //<-- Here we have mature info arrays Debug.Assert(indices[0].SequenceEqual(indices[1])); int freePointer = 0; int indexIndex; for (i = 0; i < differentIndicesCount; ++i) { //Contractions from lower to upper tensorIndex = (int)(0xFFFFFFFFL & (info[0][i] >> 16)); //From tensor index indexIndex = (int)(0xFFFFL & (info[0][i] >> 48)); ulong contraction = (0xFFFFFFFFFFFF0000L & (info[1][i] << 16)) | (0xFFFFL & info[0][i]); if (tensorIndex == -1) { freeContractions[freePointer++] = (long)contraction; } else { contractions[tensorIndex][indexIndex] = (long)contraction; } //Contractions from upper to lower tensorIndex = (int)(0xFFFFFFFFL & (info[1][i] >> 16)); //From tensor index indexIndex = (int)(0xFFFFL & (info[1][i] >> 48)); contraction = (0xFFFFFFFFFFFF0000L & (info[0][i] << 16)) | (0xFFFFL & info[1][i]); if (tensorIndex == -1) { freeContractions[freePointer++] = (long)contraction; } else { contractions[tensorIndex][indexIndex] = (long)contraction; } } }
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); }
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); }
/// <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); }
protected MultiTensor(IIndices indices) { Indices = indices; }
/// <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); }
// // 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; }
/// <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); }
public Product(IIndices indices) : base(indices) { }
/// <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; }
/// <summary> /// Draw the vertices as primitives with extended parametres, using an optional index buffer (indices) /// </summary> /// <param name="state"></param> /// <param name="indices">indices to use when drawing (may be null)</param> /// <param name="primitiveType">Primitive type to use when drawing the buffer</param> /// <param name="primitveCount">The number of primitives to draw</param> /// <param name="startIndex">The start index in the index buffer (defaults to the first index - 0)</param> /// <param name="vertexOffset">Starting offset into the vertex buffer (defaults to the first vertex - 0)</param> public void Draw(DrawState state, IIndices indices, PrimitiveType primitiveType, int primitveCount, int startIndex, int vertexOffset) { GraphicsDevice device = state.graphics; if (state.DrawTarget == null) { throw new InvalidOperationException("Vertices Draw calls should be done within the Draw() call of a DrawTarget object. (otherwise the draw target is undefined)"); } ValidateDisposed(); IDeviceIndexBuffer devib = (IDeviceIndexBuffer)indices; IndexBuffer ib = null; if (devib != null) { ib = devib.GetIndexBuffer(state); } if (decl == null) { Warm(state); } VertexBuffer vb = ((IDeviceVertexBuffer)this).GetVertexBuffer(state); VertexDeclaration vd = this.decl; #if DEBUG state.ValidateVertexDeclarationForShader(vd, typeof(VertexType)); #endif state.VertexDeclaration = vd; state.IndexBuffer = ib; state.SetStream(0, vb, 0, buffer.Stride); int vertices = buffer.Count; if (indices != null) { vertices = indices.Count; } int primitives = 0; switch (primitiveType) { case PrimitiveType.LineList: primitives = vertices / 2; break; case PrimitiveType.LineStrip: primitives = vertices - 1; break; case PrimitiveType.PointList: primitives = vertices; break; case PrimitiveType.TriangleList: primitives = vertices / 3; break; case PrimitiveType.TriangleFan: case PrimitiveType.TriangleStrip: primitives = vertices - 2; break; } int vertexCount = 0; if (indices != null) { vertexCount = indices.MaxIndex + 1; } else { switch (primitiveType) { case PrimitiveType.LineStrip: vertexCount = primitives * 2; break; case PrimitiveType.PointList: case PrimitiveType.LineList: case PrimitiveType.TriangleList: vertexCount = vertices; break; case PrimitiveType.TriangleFan: case PrimitiveType.TriangleStrip: vertexCount = primitives * 3; break; } } state.ApplyRenderStateChanges(vertexCount); if (primitveCount > primitives || primitveCount <= 0) { throw new ArgumentException("primitiveCount"); } #if DEBUG state.CalcBoundTextures(); #endif if (indices != null) { #if DEBUG System.Threading.Interlocked.Increment(ref state.Application.currentFrame.DrawIndexedPrimitiveCallCount); #endif device.DrawIndexedPrimitives(primitiveType, vertexOffset, indices.MinIndex, (indices.MaxIndex - indices.MinIndex) + 1 - vertexOffset, startIndex, primitveCount); } else { #if DEBUG System.Threading.Interlocked.Increment(ref state.Application.currentFrame.DrawPrimitivesCallCount); #endif device.DrawPrimitives(primitiveType, vertexOffset, primitveCount); } #if DEBUG switch (primitiveType) { case PrimitiveType.LineList: case PrimitiveType.LineStrip: state.Application.currentFrame.LinesDrawn += primitives; break; case PrimitiveType.PointList: state.Application.currentFrame.PointsDrawn += primitives; break; case PrimitiveType.TriangleList: case PrimitiveType.TriangleFan: case PrimitiveType.TriangleStrip: state.Application.currentFrame.TrianglesDrawn += primitives; break; } #endif }
/// <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); }
/// <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 ); }
/// <summary> /// Draw the vertices group as primitives, using an optional index buffer (indices) /// </summary> /// <param name="state"></param> /// <param name="indices">(optional) indices to use during drawing</param> /// <param name="primitiveType">Primitive type to draw, eg PrimitiveType.TriangleList</param> /// <remarks></remarks> public void Draw(DrawState state, IIndices indices, PrimitiveType primitiveType) { Draw(state, indices, primitiveType, null, int.MaxValue, 0, 0); }
public static ISimpleIndices createSimple(IndicesSymmetries symmetries, IIndices indices) { throw new NotImplementedException(); }
/// <summary> /// Draw the vertices group as primitives, using an optional index buffer (indices) and a <see cref="StreamFrequency"/> object to specify Hardware Instancing information (Shader Model 3 and Windows Only) /// </summary> /// <param name="state"></param> /// <param name="indices">(optional) indices to use during drawing</param> /// <param name="primitiveType">Primitive type to draw, eg PrimitiveType.TriangleList</param> /// <param name="frequency">(optional) <see cref="StreamFrequency"/> setting the shader model 3 instance frequency data (used for hardware instancing)</param> /// <remarks></remarks> public void Draw(DrawState state, IIndices indices, PrimitiveType primitiveType, StreamFrequency frequency) { Draw(state, indices, primitiveType, frequency, int.MaxValue, 0, 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> /// Draw the vertices group as primitives, using an optional index buffer (indices) and a <see cref="StreamFrequency"/> object to specify Hardware Instancing information (Shader Model 3 and Windows Only) /// </summary> /// <param name="state"></param> /// <param name="indices">(optional) indices to use during drawing</param> /// <param name="primitiveType">Primitive type to draw, eg PrimitiveType.TriangleList</param> /// <param name="frequency">(optional) <see cref="StreamFrequency"/> setting the shader model 3 instance frequency data (used for hardware instancing)</param> /// <param name="primitveCount">The number of primitives to draw</param> /// <param name="startIndex">The start index in the index buffer (defaults to the first index - 0)</param> /// <param name="vertexOffset">Starting offset into the vertex buffer (defaults to the first vertex - 0)</param> /// <remarks></remarks> public void Draw(DrawState state, IIndices indices, PrimitiveType primitiveType, StreamFrequency frequency, int primitveCount, int startIndex, int vertexOffset) { if (frequency != null && !state.SupportsHardwareInstancing) { throw new InvalidOperationException("Only windows devices supporting Shader Model 3.0 or better to can use hardware instancing. Check DrawState.SupportsHardwareInstancing"); } #if XBOX360 if (frequency != null) { #if DEBUG if (frequency.layout != StreamFrequency.DataLayout.Stream0Geometry_Stream1InstanceData) { throw new InvalidOperationException("Only StreamFrequency DataLayout of Stream0Geometry_Stream1InstanceData is emulated on the xbox360"); } if (primitveCount != int.MaxValue || startIndex != 0 || vertexOffset != 0) { throw new ArgumentException("Only default values for primitiveCount, startIndex and vertexOffset may be used when emulating instancing on the xbox"); } if (primitiveType == PrimitiveType.TriangleFan || primitiveType == PrimitiveType.TriangleStrip || primitiveType == PrimitiveType.LineStrip) { throw new ArgumentException("Only Primitive List Types (eg TriangleList) are supported as a primitiveType when emulating instancing on the xbox"); } #endif if (indices != null) { ((IDeviceIndexBuffer)indices).AllocateForInstancing(state); } } #endif GraphicsDevice device = state.graphics; IDeviceIndexBuffer devib = indices as IDeviceIndexBuffer; IndexBuffer ib = null; if (devib != null) { ib = devib.GetIndexBuffer(state); } if (decl == null) { decl = ((IDeviceVertexBuffer)this).GetVertexDeclaration(state.Application); } state.VertexDeclaration = decl; #if DEBUG state.ValidateVertexDeclarationForShader(decl, null); #endif int vertices = 0; for (int i = 0; i < buffers.Length; i++) { IDeviceVertexBuffer dev = buffers[i] as IDeviceVertexBuffer; if (dev != null) { state.SetStream(i, dev.GetVertexBuffer(state), offsets[i], buffers[i].Stride); } else { state.SetStream(i, null, 0, 0); } if (i == 0) { vertices = buffers[i].Count; } else if (frequency == null) { vertices = Math.Min(buffers[i].Count, vertices); } } state.IndexBuffer = ib; if (ib != null) { vertices = indices.Count; } int primitives = 0; switch (primitiveType) { case PrimitiveType.LineList: primitives = vertices / 2; break; case PrimitiveType.LineStrip: primitives = vertices - 1; break; case PrimitiveType.PointList: primitives = vertices; break; case PrimitiveType.TriangleList: primitives = vertices / 3; break; case PrimitiveType.TriangleFan: case PrimitiveType.TriangleStrip: primitives = vertices - 2; break; } int vertexCount = 0; if (indices != null) { vertexCount = indices.MaxIndex + 1; } else { switch (primitiveType) { case PrimitiveType.LineStrip: vertexCount = primitives * 2; break; case PrimitiveType.PointList: case PrimitiveType.LineList: case PrimitiveType.TriangleList: vertexCount = vertices; break; case PrimitiveType.TriangleFan: case PrimitiveType.TriangleStrip: vertexCount = primitives * 3; break; } } state.ApplyRenderStateChanges(vertexCount); #if DEBUG int instances = 1; #endif #if !XBOX360 if (frequency != null && frequency.frequency.Length >= this.buffers.Length) { #if DEBUG if (frequency.indexFrequency.Length > 0) { System.Threading.Interlocked.Increment(ref state.Application.currentFrame.InstancesDrawBatchCount); state.Application.currentFrame.InstancesDrawn += frequency.indexFrequency[0]; instances = frequency.indexFrequency[0]; } #endif for (int i = 0; i < this.buffers.Length; i++) { VertexStream vs = device.Vertices[i]; if (frequency.frequency[i] != 0) { vs.SetFrequency(frequency.frequency[i]); } if (frequency.indexFrequency[i] != 0) { vs.SetFrequencyOfIndexData(frequency.indexFrequency[i]); } if (frequency.dataFrequency[i] != 0) { vs.SetFrequencyOfInstanceData(frequency.dataFrequency[i]); } } } #endif if (primitveCount != int.MaxValue) { if (primitveCount > primitives || primitveCount <= 0) { throw new ArgumentException("primitiveCount"); } } else { primitveCount = primitives; } #if DEBUG state.CalcBoundTextures(); #endif //it is possible to have the debug runtime throw an exception here when using instancing, //as it thinks stream1 doesn't have enough data. //This is most common with sprite groups (however sprite groups will use shader-instancing with small groups) //eg, drawing a single instance requires only 64bytes in stream1, yet the triangle count could be very large //this makes the debug runtime think that stream1 doesn't have enough data if (ib != null) { #if DEBUG System.Threading.Interlocked.Increment(ref state.Application.currentFrame.DrawIndexedPrimitiveCallCount); #endif #if XBOX360 if (frequency != null) { int repeats = frequency.RepeatCount; #if DEBUG System.Threading.Interlocked.Increment(ref state.Application.currentFrame.InstancesDrawBatchCount); state.Application.currentFrame.InstancesDrawn += frequency.indexFrequency[0]; instances = repeats; #endif int maxInstances = ((IDeviceIndexBuffer)indices).MaxInstances; int offset = 0; VertexBuffer vb = ((IDeviceVertexBuffer)buffers[1]).GetVertexBuffer(state); while (repeats - offset > 0) { if (offset != 0) { //read the next set of instances state.SetStream(1, vb, offsets[1] + 64 * offset, buffers[1].Stride); } int count = Math.Min(repeats - offset, maxInstances); device.DrawIndexedPrimitives(primitiveType, vertexOffset, indices.MinIndex, ((indices.MaxIndex) + 1) - indices.MinIndex - vertexOffset, startIndex, primitveCount * count); offset += count; } } else #endif device.DrawIndexedPrimitives(primitiveType, vertexOffset, indices.MinIndex, (indices.MaxIndex - indices.MinIndex) + 1 - vertexOffset, startIndex, primitveCount); } else { #if DEBUG System.Threading.Interlocked.Increment(ref state.Application.currentFrame.DrawPrimitivesCallCount); #endif #if XBOX360 if (frequency != null) { int repeats = frequency.RepeatCount; int maxInstances = ((IDeviceIndexBuffer)indices).MaxInstances; int offset = 0; VertexBuffer vb = ((IDeviceVertexBuffer)buffers[1]).GetVertexBuffer(state); while (repeats - offset > 0) { if (offset != 0) { //read the next set of instances state.SetStream(1, vb, offsets[1] + 64 * offset, buffers[1].Stride); } int count = Math.Min(repeats - offset, maxInstances); device.DrawPrimitives(primitiveType, vertexOffset, primitveCount * count); offset += count; } } else #endif device.DrawPrimitives(primitiveType, vertexOffset, primitveCount); } #if DEBUG switch (primitiveType) { case PrimitiveType.LineList: case PrimitiveType.LineStrip: state.Application.currentFrame.LinesDrawn += primitives * instances; break; case PrimitiveType.PointList: state.Application.currentFrame.PointsDrawn += primitives * instances; break; case PrimitiveType.TriangleList: case PrimitiveType.TriangleFan: case PrimitiveType.TriangleStrip: state.Application.currentFrame.TrianglesDrawn += primitives * instances; break; } #endif #if !XBOX360 if (frequency != null && frequency.frequency.Length >= this.buffers.Length) { device.Vertices[0].SetFrequency(1); } #endif for (int i = 0; i < buffers.Length; i++) { if (i > 0) { state.SetStream(i, null, 0, 0); } } }
/// <summary> /// Draw the vertices as primitives with extended parametres, using an optional index buffer (indices) /// </summary> /// <param name="state"></param> /// <param name="indices">indices to use when drawing (may be null)</param> /// <param name="primitiveType">Primitive type to use when drawing the buffer</param> /// <param name="primitveCount">The number of primitives to draw</param> /// <param name="startIndex">The start index in the index buffer (defaults to the first index - 0)</param> /// <param name="vertexOffset">Starting offset into the vertex buffer (defaults to the first vertex - 0)</param> void IVertices.Draw(DrawState state, IIndices indices, PrimitiveType primitiveType, int primitveCount, int startIndex, int vertexOffset) { this.Draw(state, indices, primitiveType, null, primitveCount, startIndex, vertexOffset); }
public bool EqualsRegardlessOrder(IIndices indices) { return(indices.Size() == 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); }
public void Draw(DrawState state, IIndices indices, PrimitiveType primitiveType, int primitveCount, int startIndex, int vertexOffset) { ValidateDisposed(); IDeviceIndexBuffer devib = (IDeviceIndexBuffer)indices; IndexBuffer ib = null; if (devib != null) { ib = devib.GetIndexBuffer(state); } if (_vertexDeclaration == null) { _vertexDeclaration = Context.VertexDeclarationBuilder.GetDeclaration <TVertexType>(); } VertexBuffer vb = ((IDeviceVertexBuffer)this).GetVertexBuffer(state); VertexDeclaration vd = _vertexDeclaration; state.VertexDeclaration = vd; state.IndexBuffer = ib; state.SetStream(0, vb, 0, _buffer.Stride); int vertices = _buffer.Count; if (indices != null) { vertices = indices.Count; } int primitives = 0; switch (primitiveType) { case PrimitiveType.LineList: primitives = vertices / 2; break; case PrimitiveType.LineStrip: primitives = vertices - 1; break; case PrimitiveType.PointList: primitives = vertices; break; case PrimitiveType.TriangleList: primitives = vertices / 3; break; case PrimitiveType.TriangleFan: case PrimitiveType.TriangleStrip: primitives = vertices - 2; break; } int vertexCount = 0; if (indices != null) { vertexCount = indices.MaxIndex + 1; } else { switch (primitiveType) { case PrimitiveType.LineStrip: vertexCount = primitives * 2; break; case PrimitiveType.PointList: case PrimitiveType.LineList: case PrimitiveType.TriangleList: vertexCount = vertices; break; case PrimitiveType.TriangleFan: case PrimitiveType.TriangleStrip: vertexCount = primitives * 3; break; } } state.ApplyRenderStateChanges(vertexCount); if (primitveCount > primitives || primitveCount <= 0) { throw new ArgumentException("primitiveCount"); } if (indices != null) { Context.DrawIndexedPrimitive(primitiveType, vertexOffset, indices.MinIndex, (indices.MaxIndex - indices.MinIndex) + 1 - vertexOffset, startIndex, primitveCount); } else { Context.DrawPrimitives(primitiveType, vertexOffset, primitveCount); } #if DEBUG switch (primitiveType) { case PrimitiveType.LineList: case PrimitiveType.LineStrip: Context.PerformanceMonitor.IncreaseCounter(DeviceCounters.LinesDrawn, primitives); break; case PrimitiveType.PointList: Context.PerformanceMonitor.IncreaseCounter(DeviceCounters.PointsDrawn, primitives); break; case PrimitiveType.TriangleList: case PrimitiveType.TriangleFan: case PrimitiveType.TriangleStrip: Context.PerformanceMonitor.IncreaseCounter(DeviceCounters.TrianglesDrawn, primitives); break; } #endif }