At last I have something displayed. Switched to using graphics.GraphicsDevice.DrawIndexedPrimitives ... Next problem... Only one triangle is displayed. The data set is about 200 triangles. I formatted the data coming in to make sure every three consecutive vectors form a triangle face. These are irregular triangles forming an irregular shape. I don't fully understand the indexing of the vertices. Looks like each 3 indices form a triangle. If that is so then the indices match the data coming in. I did this:
int i4 = -1;
indices = new int[xData1.Count];
for (int i2 = 0; i2 < xData1.Count; i2++)
{
i4++;
cubeVertices[i4].Position = new Vector3((float)xData1[i2][0], (float)xData1[i2][1], (float)xData1[i2][2]);
cubeVertices[i4].Color = Color.LawnGreen;
indices[i4] = i4;
}
making the indices match the vertices coming in.. then I used Reimers normal calc to provide normals.. this is probably wrong as his example was using 6 vertices per index (I think!), like this:
for (int i = 0; i < cubeVertices.Length; i++)
cubeVertices[i].Normal = new Vector3(0, 0, 0);
for (int i = 0; i < indices.Length / 3; i++)
{
int index1 = indices[i * 3];
int index2 = indices[i * 3 + 1];
int index3 = indices[i * 3 + 2];
Vector3 side1 = cubeVertices[index1].Position - cubeVertices[index3].Position;
Vector3 side2 = cubeVertices[index1].Position - cubeVertices[index2].Position;
Vector3 normal = Vector3.Cross(side1, side2);
cubeVertices[index1].Normal += normal;
cubeVertices[index2].Normal += normal;
cubeVertices[index3].Normal += normal;
}
for (int i = 0; i < cubeVertices.Length; i++)
cubeVertices[i].Normal.Normalize();
how many things do I need to fix here? I am only seeing 1 out of a couple of hundred triangles
:(
thx for your patience
public struct VertexPositionColorNormal
{
public Vector3 Position;
public Color Color;
public Vector3 Normal;
public readonly static VertexDeclaration VertexDeclaration = new VertexDeclaration
(
new VertexElement(0, VertexElementFormat.Vector3, VertexElementUsage.Position, 0),
new VertexElement(sizeof(float) * 3, VertexElementFormat.Color, VertexElementUsage.Color, 0),
new VertexElement(sizeof(float) * 3 + 4, VertexElementFormat.Vector3, VertexElementUsage.Normal, 0)
);
}
...
private void CopyToBuffers()
{
vertexBuffer = new VertexBuffer(graphics.GraphicsDevice, VertexPositionColorNormal.VertexDeclaration,
cubeVertices.Length, BufferUsage.WriteOnly);
vertexBuffer.SetData(cubeVertices);
myIndexBuffer = new IndexBuffer(graphics.GraphicsDevice, typeof(int), indices.Length, BufferUsage.WriteOnly);
myIndexBuffer.SetData(indices);
}
....
foreach (EffectPass pass in basicEffect.CurrentTechnique.Passes)
{
basicEffect.World = world;
basicEffect.View = view;
basicEffect.Projection = proj;
pass.Apply();
graphics.GraphicsDevice.Indices = myIndexBuffer;
graphics.GraphicsDevice.SetVertexBuffer(vertexBuffer);
graphics.GraphicsDevice.DrawIndexedPrimitives(PrimitiveType.TriangleList, 0, 0,
cubeVertices.Length, 0, indices.Length / 3);
Your normal calculation is correct, and even if it was wrong the only thing that would happen is that your triangles would receive the wrong lightning.
You're using indices which exactly match the order of the vertices coming in, which is in itself redundant. If you switch to not setting the indices at all and use DrawPrimitives instead with the primitive count the same does that make a difference?
Other than that, are you sure that the data you're giving it is valid? Are the vertex positions correctly set?
Related
Now I have an octahedron sphere and I woud like to add noise to it, but I can' t do it because I dont know to much of this,
I think I need to modify the vertex pos but i don't know how.
Here is the script that generate the vertices, If you need More, only Ask (;
Vector3[] vertices = new Vector3[(resolution + 1) * (resolution + 1) * 4 - (resolution * 2 - 1) * 3];
int v = 0, vBottom = 0, t = 0;
for (int i = 0; i < 4; i++)
{
vertices[v++] = Vector3.down;
}
for (int i = 1; i <= resolution; i++)
{
float progress = (float)i / resolution;
Vector3 from, to;
vertices[v++] = to = Vector3.Lerp(Vector3.down, Vector3.up, progress);
for (int d = 0; d < 4; d++)
{
from = to;
to = Vector3.Lerp(Vector3.down, directions[d], progress);
t = CreateLowerStrip(i, v, vBottom, t, triangles);
v = CreateVertexLine(from, to, i, v, vertices);
vBottom += i > 1 ? (i - 1) : 1;
}
vBottom = v - 1 - i * 4;
}
Depending on how exactly your noise should look like the simplest I can imagine would be to simply iterate through the vertices and slightly shift them around by random direction vectors with a random magnitude up to a certain maximum like e.g.
void Randomize(Vector3[] vertices, float maxDistance)
{
for(var i = 0; i< vertices.Length; i++)
{
// Generates a random vactor pointing in any possible direction
var randomDirection = new Vector3(Random.Range(-1f, 1f), Random.Range(-1f, 1f), Random.Range(-1f, 1f)).normalized;
// Generate a random magnitude between 0 and given maxDistance
var randomMagnitude = Random.Range(0, maxDistance);
// Move the current vert the randomMagnitude along the randomDirection
vertices[i] += randomDirection * randomMagnitude;
}
}
Or alternatively you could only move on Vectors between the current vert position and the center (assuming Vector3.zero for now)
void RandomizeFromCenter(Vector3[] vertices, float maxDistance)
{
var center = Vector3.zero;
for(var i = 0; i< vertices.Length; i++)
{
var direction = (vertices[i] - center).normalized;
// Generate a random magnitude between -maxDistance and maxDistance
var randomMagnitude = Random.Range(-maxDistance, maxDistance);
// Move the current vert the randomMagnitude along the randomDirection
vertices[i] += direction * randomMagnitude;
}
}
I am using Unity 5 to create an isometric game. I have generated a grid of tiles and it works well. However, when I use two different tiles to fill in the grid (their image sizes are slightly different), I get gaps in between the tiles. The obvious solution would be to create the tiles so that they are all the same image size, but this would prevent me from creating anything on a tile that is larger than the size of a tile (eg. a tree).
Here are some images to demonstrate:
With only one type of tile:
With two types of tile:
This is the code I use to create the map:
private void CreateMap() {
float tileWidth;
float tileHeight;
int orderInLayer = 0;
SpriteRenderer r = floorTiles [0].GetComponent<SpriteRenderer> ();
tileWidth = r.bounds.max.x - r.bounds.min.x;
tileHeight = r.bounds.max.y - r.bounds.min.y;
for (int i = 0; i < map.GetLength(0); i++) {
orderInLayer += 1;
for (int j = 0; j < map.GetLength (1); j++) {
Vector2 position = new Vector2 ((j * tileWidth / 2) + (i * tileWidth / 2) + (tileWidth / 2), (j * tileHeight / 2) - (i * tileHeight / 2) + (tileHeight/ 2));
r = map[i,j].GetComponent<SpriteRenderer>();
r.sortingOrder = orderInLayer;
Instantiate(map[i, j], position, Quaternion.identity);
}
}
}
Any help would be greatly appreciated, I cannot seem to fix it!
You appear to be calculating a position for each of your tiles from scratch every time you create one. If you have 2 different sized tiles, then your calculation comes out different, hence the gaps in your tiles. This is because you're only using the width/height of the current tile, failing to take into account any previous tiles that may be a shorter/longer height/width.
Given you have varying heights AND widths you'll need a way to calculate the correct position for both to prevent gaps in the X and Y direction. I've mocked up something here, but it's untested. More of a concept(?) I guess.
float tileHeight = 0;
float tileWidth = 0;
Vector2 position = new Vector2(0,0);
Dictionary<int, float> HeightMap = new Dictionary<int, float>();
for (int iRow = 0; iRow < map.GetLength(0); iRow++)
{
position.x = 0;
orderInLayer += 1;
for (int jColumn = 0; jColumn < map.GetLength (1); jColumn++)
{
position.y = HeightMap[jColumn];
r = map[iRow, jColumn].GetComponent<SpriteRenderer>();
tileWidth = r.bounds.max.x - r.bounds.min.x;
tileHeight = r.bounds.max.y - r.bounds.min.y;
r.sortingOrder = orderInLayer;
position.x += tileWidth / 2;
position.y += tileHeight / 2;
Instantiate(map[iRow, jColumn], position, Quaternion.identity);
HeightMap[jColumn] = position.y;
}
}
I leave the best way of storing the height, or instantiating the contents of the HeightMap dictionary to however you see fit.
I am working on a C# .Net platform with 3D Wpf Graphics.
Here is flow of code follows:
1) I take the depth data from kinect and give it to one function which calculates 3d points.
private void display3DView()
{
while(loop_run)
{
using ( DepthImageFrame depthFrame = sensor.DepthStream.OpenNextFrame(1000))
{
if (depthFrame == null) continue;
Point3DCollection PointCloud ;
depthFrame.CopyDepthImagePixelDataTo(this.depthImagePixels);
float[,] ImageArray = new float[320, 240];
short [ ,] depth = new short[240,320];
for (int i = 0; i < 240; i++)
{
for (int j = 0; j <320; j++)
{
depth[i,j]= depthImagePixels[j+i *320].Depth;
ImageArray[i,j] =(float)depth[i,j]/(float)1000;
}
}
PointCloud =Calculate_PointCloud(ImageArray);
viewModel(PointCloud);
}
}
}</i>
2) I have calculated 3D points with Camera parameters and depth data of Kinect Camera
private Point3DCollection Calculate_PointCloud(float[,] ImageArray)
{
Point3DCollection PointCloud = new Point3DCollection();
float x_coodinate;``
float y_coordinate;
float z_coordinate;
float thresholdvalue = 2.0f;
for (int i = 0; i < 239; ++i)
{
for (int j = 0; j < 319; ++j)
{
if (Math.Abs(ImageArray[i, j] - ImageArray[i, j + 1]) < thresholdvalue && Math.Abs(ImageArray[i, j] - ImageArray[i + 1, j]) < thresholdvalue && Math.Abs(ImageArray[i, j + 1] - ImageArray[i + 1, j]) < thresholdvalue)
{
z_coordinate = ImageArray[i, j];
x_coodinate = ((j - this.PrincipalPointX) * z_coordinate) / FocalLengthX;
y_coordinate = ((i - this.PrincipalPointY) * z_coordinate) / FocalLengthY;
Point3D point1 = new Point3D(x_coodinate, y_coordinate, z_coordinate);
PointCloud.Add(point1);
z_coordinate = ImageArray[i, j + 1];
x_coodinate = (((j + 1) - this.PrincipalPointX) * z_coordinate) / FocalLengthX;
y_coordinate = ((i - this.PrincipalPointY) * z_coordinate) / FocalLengthY;
Point3D point2 = new Point3D(x_coodinate, y_coordinate, z_coordinate);
PointCloud.Add(point2);
z_coordinate = ImageArray[i + 1, j];
x_coodinate = ((j - this.PrincipalPointX) * z_coordinate) / FocalLengthX;
y_coordinate = (((i + 1) - this.PrincipalPointY) * z_coordinate) / FocalLengthY;
Point3D point3 = new Point3D(x_coodinate, y_coordinate, z_coordinate);
PointCloud.Add(point3);
}
}
}
return PointCloud;
}</i>
3)Here i converted into set of triangles with normal information of each 3D point and give those triangles to 3D mesh object and render 3d mesh object using viewport3D control
private void viewModel(Point3DCollection points)
{
DirectionalLight DirLight1 = new DirectionalLight();
DirLight1.Color = Colors.White;
DirLight1.Direction = new Vector3D(1, 1, 1);
PerspectiveCamera Camera1 = new PerspectiveCamera();
Camera1.FarPlaneDistance = 8000;
Camera1.NearPlaneDistance = 100;
Camera1.FieldOfView = 10;
Camera1.Position = new Point3D(0, 0, 1);
Camera1.LookDirection = new Vector3D(-1, -1, -1);
Camera1.UpDirection = new Vector3D(0, 1, 0);
bool combinedvertices = true;
TriangleModel Triatomesh = new TriangleModel();
MeshGeometry3D tmesh = new MeshGeometry3D();
GeometryModel3D msheet = new GeometryModel3D();
Model3DGroup modelGroup = new Model3DGroup();
ModelVisual3D modelsVisual = new ModelVisual3D();
Viewport3D myViewport = new Viewport3D();
for(int i =0; i<points.Count; i+=3)
{
Triatomesh.addTriangleToMesh(points[i],points[i + 1], points[i + 2], tmesh, combinedvertices);
}
msheet.Geometry = tmesh;
msheet.Material = new DiffuseMaterial(new SolidColorBrush(Colors.White));
modelGroup.Children.Add(msheet);
modelGroup.Children.Add(DirLight1);
modelsVisual.Content = modelGroup;
myViewport.IsHitTestVisible = false;
myViewport.Camera = Camera1;
myViewport.Children.Add(modelsVisual);
canvas1.Children.Add(myViewport);
myViewport.Height = canvas1.Height;
myViewport.Width = canvas1.Width;
Canvas.SetTop(myViewport, 0);
Canvas.SetLeft(myViewport, 0);
} </i>
4) Here is the function which takes three 3D points and add to 3d mesh object as a triangle by calculating normal to each 3D point
public void addTriangleToMesh(Point3D p0, Point3D p1, Point3D p2,
MeshGeometry3D mesh, bool combine_vertices)
{
Vector3D normal = CalculateNormal(p0, p1, p2);
if (combine_vertices)
{
addPointCombined(p0, mesh, normal);
addPointCombined(p1, mesh, normal);
addPointCombined(p2, mesh, normal);
}
else
{
mesh.Positions.Add(p0);
mesh.Positions.Add(p1);
mesh.Positions.Add(p2);
//mesh.TriangleIndices.Add(mesh.TriangleIndices.Count);
// mesh.TriangleIndices.Add(mesh.TriangleIndices.Count);
// mesh.TriangleIndices.Add(mesh.TriangleIndices.Count);
mesh.Normals.Add(normal);
mesh.Normals.Add(normal);
mesh.Normals.Add(normal);
}
}
public Vector3D CalculateNormal(Point3D P0, Point3D P1, Point3D P2) //static
{
Vector3D v0 = new Vector3D(P1.X - P0.X, P1.Y - P0.Y, P1.Z - P0.Z);
Vector3D v1 = new Vector3D(P2.X - P1.X, P2.Y - P1.Y, P2.Z - P1.Z);
return Vector3D.CrossProduct(v0, v1);
}
public void addPointCombined(Point3D point, MeshGeometry3D mesh, Vector3D normal)
{
bool found = false;
int i = 0;
foreach (Point3D p in mesh.Positions)
{
if (p.Equals(point))
{
found = true;
mesh.TriangleIndices.Add(i);
mesh.Positions.Add(point);
mesh.Normals.Add(normal);
break;
}
i++;
}
if (!found)
{
mesh.Positions.Add(point);
mesh.TriangleIndices.Add(mesh.TriangleIndices.Count);
mesh.Normals.Add(normal);
}
}
5) Here is my XAML code
<Window x:Class="PointCloud3DView.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="PointCloud" Height="653" Width="993" Background="Black" Loaded="Window_Loaded">
<Grid Height="1130" Width="1626">
<Canvas Height="611" HorizontalAlignment="Left" Name="canvas1" VerticalAlignment="Top"
Width="967" Background="Black" />
</Grid>
problem is i am not able to get displayed 3D model in Wpf Screen.Please can any one go through the whole code ? and make me understand where i go wrong? as well suggest me with corrections.
Thanks in advance
I have been experimenting with WPF 3D for several weeks now and learned some tough lessens:)
I do not have time to check and try the whole code now as I am in the work. However I would try three things:
I am not sure about direction of your camera. It is in (0,1,0),
looking using vector (-1,-1,-1), it means it is focused on central
point (-1,0,-1). And that is kinda strange... Try to position camera
further (depending on the scale of your model) like (0,10,0) or even
further and focus it to (0,0,0) or wherever central point of your
model is:
Camera1.Position = new Point3D(0, 10, 0);
Camera1.LookDirection = new Point3D(0,0,0) - Camera1.Position;
Also remove directional light (as it uses normals and if they are wrong nothing will be shown) and try ambient light instead. And your
directional lightning has just opposite vector to your looking
direction (-1,-1,-1) and (1,1,1).
Try to swap order of points in triangle indices (WPF renders only one side of the mesh, so model might be there but inside/out) -
instead of 0,1,2 try 0,2,1;
If nothing helps I will try your code once I get home.
/edited later/
Itried your code on simple triangle and rewrite it accordingy to my tips and it worked. There are some comments and two tips how to clean up your code a bit:)
private void viewModel(Point3DCollection points)
{
DirectionalLight DirLight1 = new DirectionalLight();
DirLight1.Color = Colors.White;
DirLight1.Direction = new Vector3D(1, 1, 1);
PerspectiveCamera Camera1 = new PerspectiveCamera();
Camera1.FarPlaneDistance = 8000;
//Camera1.NearPlaneDistance = 100; //close object will not be displayed with this option
Camera1.FieldOfView = 10;
//Camera1.Position = new Point3D(0, 0, 1);
//Camera1.LookDirection = new Vector3D(-1, -1, -1);
Camera1.Position = new Point3D(0, 0, 10);
Camera1.LookDirection = new Point3D(0, 0, 0) - Camera1.Position; //focus camera on real center of your model (0,0,0) in this case
Camera1.UpDirection = new Vector3D(0, 1, 0);
//you can use constructor to create Camera instead of assigning its properties like:
//PerspectiveCamera Camera1 = new PerspectiveCamera(new Point3D(0,0,10), new Vector3D(0,0,-1), new Vector3D(0,1,0), 10);
bool combinedvertices = true;
TriangleModel Triatomesh = new TriangleModel();
MeshGeometry3D tmesh = new MeshGeometry3D();
GeometryModel3D msheet = new GeometryModel3D();
Model3DGroup modelGroup = new Model3DGroup();
ModelVisual3D modelsVisual = new ModelVisual3D();
Viewport3D myViewport = new Viewport3D();
for (int i = 0; i < points.Count; i += 3)
{
Triatomesh.addTriangleToMesh(points[i + 2], points[i + 1], points[i], tmesh, combinedvertices);
//I did swap order of vertexes you may try both options with your model
}
msheet.Geometry = tmesh;
msheet.Material = new DiffuseMaterial(new SolidColorBrush(Colors.White));
//you can use constructor to create GeometryModel3D instead of assigning its properties like:
//msheet = new GeometryModel3D(tmesh, new DiffuseMaterial(new SolidColorBrush(Colors.White)));
modelGroup.Children.Add(msheet);
//use AMbientLIght instead of directional
modelGroup.Children.Add(new AmbientLight(Colors.White));
modelsVisual.Content = modelGroup;
myViewport.IsHitTestVisible = false;
myViewport.Camera = Camera1;
myViewport.Children.Add(modelsVisual);
canvas1.Children.Add(myViewport);
myViewport.Height = canvas1.Height;
myViewport.Width = canvas1.Width;
Canvas.SetTop(myViewport, 0);
Canvas.SetLeft(myViewport, 0);
}
And the Points3DCollection I used as parameter (instead of Kinect input):
Point3DCollection points = new Point3DCollection();
points.Add(new Point3D(0.5, 0, 0.5));
points.Add(new Point3D(0.5, -0.5, -0.5));
points.Add(new Point3D(-0.5, -0.1, -0.5));
viewModel(points);
I am using the following to create a circle using VertexPositionTexture:
public static ObjectData Circle(Vector2 origin, float radius, int slices)
{
/// See below
}
The texture that is applied to it doesn't look right, it spirals out from the center. I have tried some other things but nothing does it how I want. I would like for it to kind-of just fan around the circle, or start in the top-left end finish in the bottom-right. Basically wanting it to be easier to create textures for it.
I know that are MUCH easier ways to do this without using meshes, but that is not what I am trying to accomplish right now.
This is the code that ended up working thanks to Pinckerman:
public static ObjectData Circle(Vector2 origin, float radius, int slices)
{
VertexPositionTexture[] vertices = new VertexPositionTexture[slices + 2];
int[] indices = new int[slices * 3];
float x = origin.X;
float y = origin.Y;
float deltaRad = MathHelper.ToRadians(360) / slices;
float delta = 0;
float thetaInc = (((float)Math.PI * 2) / vertices.Length);
vertices[0] = new VertexPositionTexture(new Vector3(x, y, 0), new Vector2(.5f, .5f));
float sliceSize = 1f / slices;
for (int i = 1; i < slices + 2; i++)
{
float newX = (float)Math.Cos(delta) * radius + x;
float newY = (float)Math.Sin(delta) * radius + y;
float textX = 0.5f + ((radius * (float)Math.Cos(delta)) / (radius * 2));
float textY = 0.5f + ((radius * (float)Math.Sin(delta)) /(radius * 2));
vertices[i] = new VertexPositionTexture(new Vector3(newX, newY, 0), new Vector2(textX, textY));
delta += deltaRad;
}
indices[0] = 0;
indices[1] = 1;
for (int i = 0; i < slices; i++)
{
indices[3 * i] = 0;
indices[(3 * i) + 1] = i + 1;
indices[(3 * i) + 2] = i + 2;
}
ObjectData thisData = new ObjectData()
{
Vertices = vertices,
Indices = indices
};
return thisData;
}
public static ObjectData Ellipse()
{
ObjectData thisData = new ObjectData()
{
};
return thisData;
}
ObjectData is just a structure that contains an array of vertices & an array of indices.
Hope this helps others that may be trying to accomplish something similar.
It looks like a spiral because you've set the upper-left point for the texture Vector2(0,0) in the center of your "circle" and it's wrong. You need to set it on the top-left vertex of the top-left slice of you circle, because 0,0 of your UV map is the upper left corner of your texture.
I think you need to set (0.5, 0) for the upper vertex, (1, 0.5) for the right, (0.5, 1) for the lower and (0, 0.5) for the left, or something like this, and for the others use some trigonometry.
The center of your circle has to be Vector2(0.5, 0.5).
Regarding the trigonometry, I think you should do something like this.
The center of your circle has UV value of Vector2(0.5, 0.5), and for the others (supposing the second point of the sequence is just right to the center, having UV value of Vector2(1, 0.5)) try something like this:
vertices[i] = new VertexPositionTexture(new Vector3(newX, newY, 0), new Vector2(0.5f + radius * (float)Math.Cos(delta), 0.5f - radius * (float)Math.Sin(delta)));
I've just edited your third line in the for-loop. This should give you the UV coordinates you need for each point. I hope so.
I have two for loops and I wanna save that data in one array. The first for loop will create 5 rectangles in the array. After that, the second for loop will create 5 rectangles and add them to the array. But something doesn't work. I get that "Index was outside the bounds of the array" error message in the last line of the code and I don't know what to change.
int framewidth = texture.Width / sourceRects.Length;
int frameheight = texture.Height;
private void vorrück(Rectangle[] sourceRects, int framewidth, int frameheight)
{
int doublelenght = sourceRects.Length * 2;
for (int i = 0; i < sourceRects.Length; i++)
sourceRects[i] = new Rectangle(i * framewidth, 0, framewidth, frameheight);
for (int normallenght = sourceRects.Length; normallenght < doublelenght; normallenght++)
sourceRects[normallenght] = new Rectangle((sourceRects.Length - 1 - normallenght) * framewidth, 0, framewidth, frameheight);
}
You get this error because the size of your Rectangle[] array is smaller than 10. Keep in mind that when you declare your Rectangle[] array, you should at least declare it with a size of 10.
Rectangle[] sourceRects = new Rectangle[10]; //(it will be from 0 to 9)
You will then be able to add 10 rectangles to it.
You need a bigger array.
The second loop very clearly writes outside the bounds, the relevant details are:
for (int normallenght = sourceRects.Length; ...; ...)
sourceRects[normallenght] = ...; // normallenght >= sourceRects.Length
As a general solution, do not use arrays so much. In this case a List<Rectangle> is probably the preferred datastructure.
You have made 2 mistakes (missing resize and second for never works).
Look at my modified code:
private void vorrück(ref Rectangle[] sourceRects, int framewidth, int frameheight)
{
int doublelenght = sourceRects.Length * 2;
for (int i = 0; i < sourceRects.Length; i++)
{
sourceRects[i] = new Rectangle(i * framewidth, 0, framewidth, frameheight);
}
Array.Resize(ref sourceRects, doublelenght);
for (int normallenght = sourceRects.Length /2; normallenght < doublelenght; normallenght++)
{
sourceRects[normallenght] = new Rectangle((sourceRects.Length - 1 - normallenght) * framewidth, 0, framewidth, frameheight);
}
}
This code will resize and fill your sourceRects array.
You can use this code like this:
Rectangle[] sourceRects = new Rectangle[2];
vorrück(ref sourceRects,5,4);