public override MeshDraw CreateDebugPrimitive(GraphicsDevice device) { if (cachedDebugPrimitive != null) return cachedDebugPrimitive; var verts = new VertexPositionNormalTexture[pointsList.Count]; for (var i = 0; i < pointsList.Count; i++) { verts[i].Position = pointsList[i]; verts[i].TextureCoordinate = Vector2.Zero; verts[i].Normal = Vector3.Zero; } var intIndices = indicesList.Select(x => (int)x).ToArray(); ////calculate basic normals ////todo verify, winding order might be wrong? for (var i = 0; i < indicesList.Count; i += 3) { var i1 = intIndices[i]; var i2 = intIndices[i + 1]; var i3 = intIndices[i + 2]; var a = verts[i1]; var b = verts[i2]; var c = verts[i3]; var n = Vector3.Cross((b.Position - a.Position), (c.Position - a.Position)); n.Normalize(); verts[i1].Normal = verts[i2].Normal = verts[i3].Normal = n; } var meshData = new GeometricMeshData<VertexPositionNormalTexture>(verts, intIndices, false); cachedDebugPrimitive = new GeometricPrimitive(device, meshData).ToMeshDraw(); return cachedDebugPrimitive; }
/// <summary> /// Create a new model. /// </summary> /// <param name="game"></param> /// <param name="shapeArray"></param> /// <param name="textureName"></param> /// <param name="collisionRadius"></param> /// //Create a textured model with normals public MyModel(LabGame game, VertexPositionNormalTexture[] shapeArray, String textureName, float collisionRadius) { this.vertices = Buffer.Vertex.New(game.GraphicsDevice, shapeArray); this.inputLayout = VertexInputLayout.New<VertexPositionNormalTexture>(0); vertexStride = Utilities.SizeOf<VertexPositionNormalTexture>(); modelType = ModelType.Textured; Texture = game.Content.Load<Texture2D>(textureName); this.collisionRadius = collisionRadius; wasLoaded = false; }
private void CreateVertexBuffer() { var vertices = new VertexPositionNormalTexture[_sourceMesh.Positions.Count]; for (int i = 0; i < _sourceMesh.Positions.Count; i++) { vertices[i].Position = ConversionUtility.ToSharpDXVector3(_sourceMesh.Positions[i]); vertices[i].Normal = ConversionUtility.ToSharpDXVector3(_sourceMesh.Normals[i]); if (_sourceMesh.TextureCoordinates.Count - 1 >= i) vertices[i].TextureCoordinate = new Vector2(_sourceMesh.TextureCoordinates[i].X, _sourceMesh.TextureCoordinates[i].Y); } _vertexBuffer = Buffer.Vertex.New(_device, vertices); }
/// <summary> /// Creates a Plane primitive on the X/Y plane with a normal equal to -<see cref="Vector3.UnitZ" />. /// </summary> /// <param name="device">The device.</param> /// <param name="sizeX">The size X.</param> /// <param name="sizeY">The size Y.</param> /// <param name="tessellation">The tessellation, as the number of quads per axis.</param> /// <param name="uvFactor">The uv factor.</param> /// <param name="toLeftHanded">if set to <c>true</c> vertices and indices will be transformed to left handed. Default is true.</param> /// <returns>A Plane primitive.</returns> /// <exception cref="System.ArgumentOutOfRangeException">tessellation;tessellation must be > 0</exception> public static GeometricPrimitive New(GraphicsDevice device, float sizeX, float sizeY, int tessellation, Vector2 uvFactor, bool toLeftHanded = false) { if (tessellation < 1) { throw new ArgumentOutOfRangeException("tessellation", "tessellation must be > 0"); } var lineWidth = tessellation + 1; var vertices = new VertexPositionNormalTexture[lineWidth * lineWidth]; var indices = new int[tessellation * tessellation * 6]; var deltaX = sizeX/tessellation; var deltaY = sizeY/tessellation; sizeX /= 2.0f; sizeY /= 2.0f; int vertexCount = 0; int indexCount = 0; var normal = Vector3.UnitZ; // Create vertices for (int y = 0; y < (tessellation+1); y++) { for (int x = 0; x < (tessellation+1); x++) { var position = new Vector3(-sizeX + deltaX * x, sizeY - deltaY * y, 0); var texCoord = new Vector2(1.0f * x / tessellation * uvFactor.X, 1.0f * y / tessellation * uvFactor.Y); vertices[vertexCount++] = new VertexPositionNormalTexture(position, normal, texCoord); } } // Create indices for (int y = 0; y < tessellation; y++) { for (int x = 0; x < tessellation; x++) { // Six indices (two triangles) per face. int vbase = lineWidth * y + x; indices[indexCount++] = (vbase + 1); indices[indexCount++] = (vbase + 1 + lineWidth); indices[indexCount++] = (vbase + lineWidth); indices[indexCount++] = (vbase + 1); indices[indexCount++] = (vbase + lineWidth); indices[indexCount++] = (vbase ); } } // Create the primitive object. return new GeometricPrimitive(device, vertices, indices, toLeftHanded) { Name = "Plane"}; }
/// <summary> /// Appends local mesh data transformed with and object transform /// </summary> /// <param name="meshData"></param> /// <param name="objectTransform"></param> public void AppendMeshData(GeometricMeshData <VertexPositionNormalTexture> meshData, Matrix objectTransform) { // Transform box points int vbase = Points.Count; for (int i = 0; i < meshData.Vertices.Length; i++) { VertexPositionNormalTexture point = meshData.Vertices[i]; point.Position = Vector3.Transform(point.Position, objectTransform).XYZ(); Points.Add(point.Position); BoundingBox.Merge(ref BoundingBox, ref point.Position, out BoundingBox); } // Copy indices with offset applied for (int i = 0; i < meshData.Indices.Length; i++) { Indices.Add(meshData.Indices[i] + vbase); } }
private void CreatePlane() { // size of 3D Axis float PlaneLenght = 100f; float repetition = 6f; // Number of vertices we´ll use int vertexCount = 4; VertexPositionNormalTexture[] vertices = new VertexPositionNormalTexture[vertexCount]; // X axis vertices[0] = new VertexPositionNormalTexture(new Vector3(-PlaneLenght, 0.0f, -PlaneLenght), Vector3.Up, new Vector2(0f, repetition)); vertices[1] = new VertexPositionNormalTexture(new Vector3(PlaneLenght, 0.0f, -PlaneLenght), Vector3.Up, new Vector2(repetition, repetition)); vertices[2] = new VertexPositionNormalTexture(new Vector3(-PlaneLenght, 0.0f, PlaneLenght), Vector3.Up, new Vector2(0f, 0f)); vertices[3] = new VertexPositionNormalTexture(new Vector3(PlaneLenght, 0.0f, PlaneLenght), Vector3.Up, new Vector2(repetition, 0f)); // fill the vertex buffer with the vertices vertexBuffer = new VertexBuffer(device, VertexPositionNormalTexture.VertexDeclaration, vertexCount, BufferUsage.WriteOnly); vertexBuffer.SetData <VertexPositionNormalTexture>(vertices); }
public BoundingBox CreateBoundingBox(Model model) { Vector3 max = Vector3.Zero; Vector3 min = Vector3.Zero; foreach (ModelMesh mesh in model.Meshes) { int vertexCount = mesh.VertexBuffer.SizeInBytes / VertexPositionNormalTexture.SizeInBytes; VertexPositionNormalTexture[] verts = new VertexPositionNormalTexture[vertexCount]; mesh.VertexBuffer.GetData(verts); for (int i = 0; i < vertexCount; i++) { if (min.X > verts[i].Position.X) { min.X = verts[i].Position.X; } if (max.X < verts[i].Position.X) { max.X = verts[i].Position.X; } if (min.Y > verts[i].Position.Y) { min.Y = verts[i].Position.Y; } if (max.Y < verts[i].Position.Y) { max.Y = verts[i].Position.Y; } if (min.Z > verts[i].Position.Z) { min.Z = verts[i].Position.Z; } if (max.Z < verts[i].Position.Z) { max.Z = verts[i].Position.Z; } } } return(new BoundingBox(min, max)); }
private void SetNormalToTriangle(List <VertexPositionNormalTexture> vertices, int firstVectorIndex, int secondVectorIndex, int thirdVectorIndex) { VertexPositionNormalTexture firstV = vertices.ElementAt(firstVectorIndex); VertexPositionNormalTexture secondV = vertices.ElementAt(secondVectorIndex); VertexPositionNormalTexture thirdV = vertices.ElementAt(thirdVectorIndex); Vector3 newNormal = CalculateNormal(firstV.Position, secondV.Position, thirdV.Position); firstV.Normal = newNormal; secondV.Normal = newNormal; thirdV.Normal = newNormal; vertices[firstVectorIndex] = firstV; vertices[secondVectorIndex] = secondV; vertices[thirdVectorIndex] = thirdV; }
public void OffsetAllVerts(Vector3 offset) { if (!hasBegun) { throw new Exception("Can't offset verts without beginning a new mesh"); } for (int i = 0; i < softVerts.Count; i++) { VertexPositionNormalTexture vert = softVerts[i]; softVerts[i] = new VertexPositionNormalTexture(vert.Position + offset, vert.Normal, vert.TextureCoordinate); } for (int i = 0; i < hardVerts.Count; i++) { VertexPositionNormalTexture vert = hardVerts[i]; hardVerts[i] = new VertexPositionNormalTexture(vert.Position + offset, vert.Normal, vert.TextureCoordinate); } }
private void SetUpVertices() { bool vdec = true, uinc = true; int width = heightMap.Width; int height = heightMap.Height; int incrementCount, tuCount, tvCount; float incrementValue, tuCoordinate, tvCoordinate; incrementValue = (float)TEXTURE_REPEAT / (float)height; incrementCount = height / TEXTURE_REPEAT; tuCoordinate = 0.0f; tvCoordinate = 1.0f; tuCount = 0; tvCount = 0; vertices = new VertexPositionNormalTexture[width * height]; for (int x = 0; x < width; x++) { for (int y = 0; y < height; y++) { Vector2 uv = new Vector2(tuCoordinate, tvCoordinate); vertices[x + y * width] = new VertexPositionNormalTexture( new Vector3(x, heightData[x, y], y), Vector3.Up, uv); tvCoordinate = vdec ? tvCoordinate - incrementValue : tvCoordinate + incrementValue; tvCount++; if (tvCount == incrementCount) { tvCoordinate = vdec ? 0.0f : 1.0f; tvCount = 0; vdec = !vdec; } } tuCoordinate = uinc ? tuCoordinate + incrementValue : tuCoordinate - incrementValue; tuCount++; if (tuCount == incrementCount) { tuCoordinate = uinc ? 1.0f : 0.0f; tuCount = 0; uinc = !uinc; } } }
protected override void InitializeVertices(string filePath) { InitialPoints = new[] { new Vector4(-4.0f, 0.0f, -4.0f, 1.0f), new Vector4(-4.0f, 0.0f, 4.0f, 1.0f), new Vector4(4.0f, 0.0f, 4.0f, 1.0f), new Vector4(-4.0f, 0.0f, -4.0f, 1.0f), new Vector4(4.0f, 0.0f, 4.0f, 1.0f), new Vector4(4.0f, 0.0f, -4.0f, 1.0f), }; var textCoords = new[] { new Vector2(0f, 1f), new Vector2(0f, 0f), new Vector2(1, 0f), new Vector2(0f, 1f), new Vector2(1f, 0f), new Vector2(1f, 1f), }; var normals = new[] { new Vector4(-4.0f, 1.0f, -4.0f, 0.0f), new Vector4(-4.0f, 1.0f, 4.0f, 0.0f), new Vector4(4.0f, 1.0f, 4.0f, 0.0f), new Vector4(-4.0f, 1.0f, -4.0f, 0.0f), new Vector4(4.0f, 1.0f, 4.0f, 0.0f), new Vector4(4.0f, 1.0f, -4.0f, 0.0f), }; VerticesCount = InitialPoints.Length; Vertices = new VertexPositionNormalTexture[VerticesCount]; for (var i = 0; i < VerticesCount; i++) { Vertices[i].Position = InitialPoints[i]; Vertices[i].Normal = normals[i]; Vertices[i].Texture = textCoords[i]; } InitialVertices = Vertices; }
public static MeshData Plane(int width, int height, int uvUnit) { float halfWidth = width / 2; float halfHeight = height / 2; Vector2 uvScale = new Vector2(width / uvUnit, height / uvUnit); VertexPositionNormalTexture[] vertices = new VertexPositionNormalTexture[] { new VertexPositionNormalTexture(new Vector3(-halfWidth, 0, -halfHeight), Vector3.UnitY, new Vector2(0, 0) * uvScale), new VertexPositionNormalTexture(new Vector3(halfWidth, 0, -halfHeight), Vector3.UnitY, new Vector2(1, 0) * uvScale), new VertexPositionNormalTexture(new Vector3(halfWidth, 0, halfHeight), Vector3.UnitY, new Vector2(1, 1) * uvScale), new VertexPositionNormalTexture(new Vector3(-halfWidth, 0, halfHeight), Vector3.UnitY, new Vector2(0, 1) * uvScale), }; ushort[] indices = new ushort[] { 0, 1, 2, 0, 2, 3 }; return(new SimpleMeshDataProvider(vertices, indices)); }
public override void Draw(GameTime gameTime) { if (isPlayerEnoughNearToDraw()) { float minY = float.MaxValue; float maxY = float.MinValue; var world = CurPosition; var view = Maps.MapRepo.CurrentMap.Camera.View; var projection = Maps.MapRepo.CurrentMap.Camera.Projection; var mesh = Model.Meshes.FirstOrDefault(); if (mesh != null) { foreach (var part in mesh.MeshParts) { int count = part.NumVertices; VertexPositionNormalTexture[] positions = new VertexPositionNormalTexture[count]; part.VertexBuffer.GetData(positions); foreach (var position in positions) { if (position.Position.Z < minY) { minY = position.Position.Z; } if (position.Position.Z > maxY) { maxY = position.Position.Z; } } part.Effect = DeathEffect; var worldMatrix = world; DeathEffect.Parameters["World"].SetValue(worldMatrix); DeathEffect.Parameters["View"].SetValue(view); DeathEffect.Parameters["Projection"].SetValue(projection); DeathEffect.Parameters["ModelTexture"].SetValue(Texture); DeathEffect.Parameters["Time"]?.SetValue(AnimationTime); DeathEffect.Parameters["minY"]?.SetValue(minY); DeathEffect.Parameters["maxY"]?.SetValue(maxY); DeathEffect.Parameters["InverseTransposeWorld"].SetValue(Matrix.Transpose(Matrix.Invert(worldMatrix))); } mesh.Draw(); } } }
// /// <summary> // /// Build a terrain patch. // /// </summary> // /// <param name="game"></param> // /// <param name="heightmap"></param> // /// <param name="worldMatrix"></param> // /// <param name="width"></param> // /// <param name="depth"></param> // /// <param name="offsetX"></param> // /// <param name="offsetZ"></param> // public static void BuildPatch(Game game, Heightmap heightmap, Matrix worldMatrix, int width, int depth, int offsetX, int offsetZ) // { // // } /// <summary> /// Build the vertex buffer as well as the bounding box. /// </summary> /// <param name="heightmap"></param> private void BuildVertexBuffer(Heightmap heightmap) { int index = 0; _boundingBox.Min.Y = float.MaxValue; _boundingBox.Max.Y = float.MinValue; Geometry = new VertexPositionNormalTexture[Width * Depth]; for (int z = _offsetZ; z < _offsetZ + Depth; ++z) { for (int x = _offsetX; x < _offsetX + Width; ++x) { // We need to connect the patches by increasing each patch width and depth by 1, // but this means the patches along some of the edges will run out of // heightmap data, so make sure we cap the index at the edge int cappedX = Math.Min(x, heightmap.Width - 1); int cappedZ = Math.Min(z, heightmap.Depth - 1); float height = heightmap.GetHeightValue(cappedX, cappedZ); if (height < _boundingBox.Min.Y) { _boundingBox.Min.Y = height; } if (height > _boundingBox.Max.Y) { _boundingBox.Max.Y = height; } var position = new Vector3(x, height, z); Vector3 normal; ComputeVertexNormal(heightmap, cappedX, cappedZ, out normal); Geometry[index] = new VertexPositionNormalTexture(position, normal, new Vector2(x, z)); ++index; } } }
public void GenerateVerticesWithSubsection(int x, int y, int width, int height) { //0.0f float xp = (float)x / Texture.Width; float yp = (float)y / Texture.Height; // 1.0f float xw = (float)(x + width) / Texture.Width; float yw = (float)(y + height) / Texture.Height; Vertices = new VertexPositionNormalTexture[6]; Vertices[0] = genVertice(-1.0f, 1.0f, 0, xp, yp); Vertices[1] = genVertice(1.0f, 1.0f, 0, xw, yp); Vertices[2] = genVertice(-1.0f, -1.0f, 0, xp, yw); Vertices[3] = genVertice(-1.0f, -1.0f, 0, xp, yw); Vertices[4] = genVertice(1.0f, 1.0f, 0, xw, yp); Vertices[5] = genVertice(1.0f, -1.0f, 0, xw, yw); }
public void RotateAllVerts(Quaternion rot) { if (!hasBegun) { throw new Exception("Can't rotate verts without beginning a new mesh"); } for (int i = 0; i < softVerts.Count; i++) { VertexPositionNormalTexture vert = softVerts[i]; softVerts[i] = new VertexPositionNormalTexture(Vector3.Transform(vert.Position, rot), Vector3.TransformNormal(vert.Normal, Matrix.CreateFromQuaternion(rot)), vert.TextureCoordinate); } for (int i = 0; i < hardVerts.Count; i++) { VertexPositionNormalTexture vert = hardVerts[i]; hardVerts[i] = new VertexPositionNormalTexture(Vector3.Transform(vert.Position, rot), Vector3.TransformNormal(vert.Normal, Matrix.CreateFromQuaternion(rot)), vert.TextureCoordinate); } }
private void UpdateWaterVertices(Map owner) { VertexPositionNormalTexture[] vertexdata = new VertexPositionNormalTexture[4]; short[] indexdata = new short[4]; float xmax = owner.Ground.Zoom * owner.Ground.Width; float ymax = owner.Ground.Zoom * owner.Ground.Height; Vector3[] position = new Vector3[4]; Vector2[] tex = new Vector2[4]; float x0 = (-owner.Ground.Width / 2) * owner.Ground.Zoom; float x1 = ((owner.Ground.Width - 1) - owner.Ground.Width / 2 + 1) * owner.Ground.Zoom; float z0 = (-owner.Ground.Height / 2) * owner.Ground.Zoom; float z1 = ((owner.Ground.Height - 1) - owner.Ground.Height / 2 + 1) * owner.Ground.Zoom; position[0] = new Vector3(x0, _waterInfo.Level, z0); position[1] = new Vector3(x1, _waterInfo.Level, z0); position[2] = new Vector3(x0, _waterInfo.Level, z1); position[3] = new Vector3(x1, _waterInfo.Level, z1); tex[0] = new Vector2(0, 0); tex[1] = new Vector2(owner.Ground.Width / 8, 0); tex[2] = new Vector2(0, owner.Ground.Height / 8); tex[3] = new Vector2(owner.Ground.Width / 8, owner.Ground.Height / 8); vertexdata[0] = new VertexPositionNormalTexture(position[0], new Vector3(1.0F), tex[0]); vertexdata[1] = new VertexPositionNormalTexture(position[1], new Vector3(1.0F), tex[1]); vertexdata[2] = new VertexPositionNormalTexture(position[2], new Vector3(1.0F), tex[2]); vertexdata[3] = new VertexPositionNormalTexture(position[3], new Vector3(1.0F), tex[3]); indexdata[0] = 0; indexdata[1] = 1; indexdata[2] = 2; indexdata[3] = 3; _vertices = new VertexBuffer(_graphicsDevice, typeof(VertexPositionNormalTexture), 4, BufferUsage.WriteOnly); _vertices.SetData(vertexdata); _indexes = new IndexBuffer(_graphicsDevice, typeof(short), 4, BufferUsage.WriteOnly); _indexes.SetData(indexdata); }
public void Update(Vector2 position, Vector2 velocity, float alpha) { _time.Update(); if (_time.Ready == true) { nodes.Insert(0, new PosAndVelocity(position, velocity)); if (nodes.Count > _number) { nodes.RemoveAt(_number); } _time.Reset(); } _alpha = alpha; float UVOff = 1f / _number; for (int i = 0; i < nodes.Count; i++) { vertices[i * 2] = new VertexPositionNormalTexture(new Vector3(nodes[i].Position.ShiftOverDistance(_width / 2, nodes[i].Velocity.ToAngle() - (float)(Math.PI / 2)), 0), new Vector3(nodes[i].Velocity.X, nodes[i].Velocity.Y, 0), new Vector2(0, i * UVOff)); vertices[i * 2 + 1] = new VertexPositionNormalTexture(new Vector3(nodes[i].Position.ShiftOverDistance(_width / 2, nodes[i].Velocity.ToAngle() + (float)(Math.PI / 2)), 0), new Vector3(nodes[i].Velocity.X, nodes[i].Velocity.Y, 0), new Vector2(1, i * UVOff)); } VertexBuffer.SetData(vertices); int number = 2; for (int i = 0; i < (indices.GetLength(0) / 6); i++) { indices[i * 6 + 0] = (short)(0 + i * number); indices[i * 6 + 1] = (short)(1 + i * number); indices[i * 6 + 2] = (short)(2 + i * number); indices[i * 6 + 3] = (short)(2 + i * number); indices[i * 6 + 4] = (short)(1 + i * number); indices[i * 6 + 5] = (short)(3 + i * number); } IndexBuffer.SetData(indices); }
public void AddFloor(Vector3 LL, int height, int textureID) { VertexPositionNormalTexture lowerLeft, lowerRight, upperLeft, upperRight; LL = LL + Vector3.UnitZ * height * Constants.TILE_SIZE; lowerLeft = new VertexPositionNormalTexture(LL, Vector3.UnitZ, TCLL); lowerRight = new VertexPositionNormalTexture(LL + Vector3.UnitX * Constants.TILE_SIZE, Vector3.UnitZ, TCLR); upperLeft = new VertexPositionNormalTexture(LL + Vector3.UnitY * Constants.TILE_SIZE, Vector3.UnitZ, TCUL); upperRight = new VertexPositionNormalTexture(LL + (Vector3.UnitY + Vector3.UnitX) * Constants.TILE_SIZE , Vector3.UnitZ, TCUR); if (height <= 1) { if (!FloorTextureGroups.ContainsKey(textureID)) { VertexGroup gp = new VertexGroup(TileList.GetTile(textureID)); gp.Technique = RendererAssetPool.UniversalEffect.Techniques.TexturedClamp; FloorTextureGroups.Add(textureID, gp); } FloorTextureGroups[textureID].Add(lowerLeft); FloorTextureGroups[textureID].Add(upperLeft); FloorTextureGroups[textureID].Add(lowerRight); FloorTextureGroups[textureID].Add(lowerRight); FloorTextureGroups[textureID].Add(upperLeft); FloorTextureGroups[textureID].Add(upperRight); } else { if (!WallTextureGroups.ContainsKey(textureID)) { VertexGroup gp = new VertexGroup(TileList.GetTile(textureID)); gp.TransparencyEnabled = true; gp.Technique = RendererAssetPool.UniversalEffect.Techniques.TexturedWrap; WallTextureGroups.Add(textureID, gp); } WallTextureGroups[textureID].Add(lowerLeft); WallTextureGroups[textureID].Add(upperLeft); WallTextureGroups[textureID].Add(lowerRight); WallTextureGroups[textureID].Add(lowerRight); WallTextureGroups[textureID].Add(upperLeft); WallTextureGroups[textureID].Add(upperRight); } }
public override void Initialize() { MiniInit(); for (int i = 0; i < vertices.Length; i++) { VertexPositionNormalTexture vertex = vertices[i]; if (dir == Tile.Direction.NORTH) { vertex.Position.X = (i > 1) ? mapX * Tile.SIZE : (mapX + 1) * Tile.SIZE; vertex.Position.Y = (mapY + 1) * Tile.SIZE; } if (dir == Tile.Direction.SOUTH) { vertex.Position.X = (i <= 1) ? mapX * Tile.SIZE : (mapX + 1) * Tile.SIZE; vertex.Position.Y = mapY * Tile.SIZE; } if (dir == Tile.Direction.EAST) { vertex.Position.X = (mapX + 1) * Tile.SIZE; vertex.Position.Y = (i <= 1) ? mapY * Tile.SIZE : (mapY + 1) * Tile.SIZE; } if (dir == Tile.Direction.WEST) { vertex.Position.X = (mapX * Tile.SIZE); vertex.Position.Y = (i > 1) ? mapY * Tile.SIZE : (mapY + 1) * Tile.SIZE; } vertex.Position.Z = (i % 2 == 0) ? mapZ * Tile.HEIGHT : (mapZ + 1) * Tile.HEIGHT; vertices[i] = vertex; } if (section.Width == 0) { section = new Rectangle(0, 0, texture.Width, texture.Height); } percentOpen = 1; UpdateVerts(null); }
private void CreateChildNodes(VertexPositionNormalTexture[,] vertexArray, int maxSize) { VertexPositionNormalTexture[,] ulArray = new VertexPositionNormalTexture[width / 2 + 1, height / 2 + 1]; for (int w = 0; w < width / 2 + 1; w++) { for (int h = 0; h < height / 2 + 1; h++) { ulArray[w, h] = vertexArray[w, h]; } } nodeUL = new QTNode(ulArray, device, grassTexture, maxSize); VertexPositionNormalTexture[,] urArray = new VertexPositionNormalTexture[width - (width / 2), height / 2 + 1]; for (int w = 0; w < width - (width / 2); w++) { for (int h = 0; h < height / 2 + 1; h++) { urArray[w, h] = vertexArray[width / 2 + w, h]; } } nodeUR = new QTNode(urArray, device, grassTexture, maxSize); VertexPositionNormalTexture[,] llArray = new VertexPositionNormalTexture[width / 2 + 1, height - (height / 2)]; for (int w = 0; w < width / 2 + 1; w++) { for (int h = 0; h < height - (height / 2); h++) { llArray[w, h] = vertexArray[w, height / 2 + h]; } } nodeLL = new QTNode(llArray, device, grassTexture, maxSize); VertexPositionNormalTexture[,] lrArray = new VertexPositionNormalTexture[width - (width / 2), height - (height / 2)]; for (int w = 0; w < width - (width / 2); w++) { for (int h = 0; h < height - (height / 2); h++) { lrArray[w, h] = vertexArray[width / 2 + w, height / 2 + h]; } } nodeLR = new QTNode(lrArray, device, grassTexture, maxSize); }
public static void GetShapeMeshData(EntityCollidable collidable, List <VertexPositionNormalTexture> vertices, List <ushort> indices) { var compoundCollidable = collidable as CompoundCollidable; if (compoundCollidable == null) { throw new ArgumentException("Wrong shape type."); } var tempIndices = new List <ushort>(); var tempVertices = new List <VertexPositionNormalTexture>(); for (int i = 0; i < compoundCollidable.Children.Count; i++) { var child = compoundCollidable.Children[i]; ModelDrawer.ShapeMeshGetter shapeMeshGetter; if (ModelDrawer.ShapeMeshGetters.TryGetValue(child.CollisionInformation.GetType(), out shapeMeshGetter)) { shapeMeshGetter(child.CollisionInformation, tempVertices, tempIndices); for (int j = 0; j < tempIndices.Count; j++) { indices.Add((ushort)(tempIndices[j] + vertices.Count)); } var localTransform = child.Entry.LocalTransform; var localPosition = child.CollisionInformation.LocalPosition; var orientation = localTransform.Orientation; var position = localTransform.Position; for (int j = 0; j < tempVertices.Count; j++) { VertexPositionNormalTexture vertex = tempVertices[j]; Vector3.Add(ref vertex.Position, ref localPosition, out vertex.Position); Vector3.Transform(ref vertex.Position, ref orientation, out vertex.Position); Vector3.Add(ref vertex.Position, ref position, out vertex.Position); Vector3.Transform(ref vertex.Normal, ref orientation, out vertex.Normal); vertices.Add(vertex); } tempVertices.Clear(); tempIndices.Clear(); } } }
// generates a zero-width quad for each line in the blob collection, with texture and color // arrow texture will point in the direction the nodes are given in internal static BasicVertexBuffer GenerateDebugLines(GraphicsDevice graphicsDevice, BlobCollection blobs) { List <int> indices = new List <int>(); List <VertexPositionNormalTexture> vertices = new List <VertexPositionNormalTexture>(); foreach (Way way in blobs.EnumerateWays()) { long?prev = null; foreach (var nodeRef in way.refs) { long?v = blobs.nodes.ContainsKey(nodeRef) ? nodeRef : (long?)null; if (prev != null && v != null) { Vector2d pos1 = blobs.nodes[prev.Value]; Vector2d pos2 = blobs.nodes[v.Value]; float length = (float)(pos2 - pos1).Length(); // unfortunately calculating the normal from the next/prev vertex in the vertexshader has issues, due to WVP inaccuracies of offscreen vertices Vector2d normalRight = (pos2 - pos1).RotateCW90().Normalized(); Vector2d normalLeft = (pos2 - pos1).RotateCCW90().Normalized(); // the top of the image will be at the end of the path var topLeft = new VertexPositionNormalTexture(new Vector3(pos2, 0), new Vector3(normalLeft, 0), new Vector2(0, 0)); var topRight = new VertexPositionNormalTexture(new Vector3(pos2, 0), new Vector3(normalRight, 0), new Vector2(1, 0)); var bottomLeft = new VertexPositionNormalTexture(new Vector3(pos1, 0), new Vector3(normalLeft, 0), new Vector2(0, length)); var bottomRight = new VertexPositionNormalTexture(new Vector3(pos1, 0), new Vector3(normalRight, 0), new Vector2(1, length)); vertices.Add(topLeft); vertices.Add(topRight); vertices.Add(bottomLeft); vertices.Add(bottomRight); // TODO: undo the bad flipping when we're ready int i = vertices.Count - 4; indices.Add(i); indices.Add(i + 3); indices.Add(i + 1); indices.Add(i); indices.Add(i + 2); indices.Add(i + 3); } prev = v; } } return(new BasicVertexBuffer(graphicsDevice, indices, vertices, GlobalContent.CCWArrows, true, PrimitiveType.TriangleList)); }
protected override void InitialiserSommets() { int NoSommet = -1; for (int j = 0; j < NbRangées - 1; j++) { for (int i = 0; i < NbColonnes - 1; i++) { Sommets[++NoSommet] = new VertexPositionNormalTexture(PtsSommets[(i) + j * NbColonnes], new Vector3(0, 0, 0), PtsTexture[0, ObtenirPtTexture(i, j)]); Sommets[++NoSommet] = new VertexPositionNormalTexture(PtsSommets[(i) + (j + 1) * NbColonnes], new Vector3(0, 0, 0), PtsTexture[0, ObtenirPtTexture(i, j) + 1]); Sommets[++NoSommet] = new VertexPositionNormalTexture(PtsSommets[(i + 1) + j * NbColonnes], new Vector3(0, 0, 0), PtsTexture[1, ObtenirPtTexture(i, j)]); Sommets[++NoSommet] = new VertexPositionNormalTexture(PtsSommets[(i + 1) + j * NbColonnes], new Vector3(0, 0, 0), PtsTexture[1, ObtenirPtTexture(i, j)]); Sommets[++NoSommet] = new VertexPositionNormalTexture(PtsSommets[(i) + (j + 1) * NbColonnes], new Vector3(0, 0, 0), PtsTexture[0, ObtenirPtTexture(i, j) + 1]); Sommets[++NoSommet] = new VertexPositionNormalTexture(PtsSommets[(i + 1) + (j + 1) * NbColonnes], new Vector3(0, 0, 0), PtsTexture[1, ObtenirPtTexture(i, j) + 1]); } } CalculateNormals(); }
/// <summary> /// Creates the terrain vertex buffer /// </summary> private void InitializeVertices() { VertexPositionNormalTexture[] terrainVertices = new VertexPositionNormalTexture[width * height]; int i = 0; for (int z = 0; z < height; z++) { for (int x = 0; x < width; x++) { terrainVertices[i].Position = new Vector3(x, heights[x, z], -z); terrainVertices[i].Normal = Vector3.Up; terrainVertices[i].TextureCoordinate = new Vector2((float)x / 50f, (float)z / 50f); i++; } } vertices = new VertexBuffer(game.GraphicsDevice, typeof(VertexPositionNormalTexture), terrainVertices.Length, BufferUsage.None); vertices.SetData <VertexPositionNormalTexture>(terrainVertices); }
public void LoadContent() { // load the shader oceanEffect = GameStateManager.Instance.Content.Load <Effect>("Effects/OceanShader"); // load the normal maps OceanNormalMaps = new Texture2D[4]; for (int i = 0; i < 4; i++) { OceanNormalMaps[i] = GameStateManager.Instance.Content.Load <Texture2D>("Textures/Ocean" + (i + 1) + "_N"); } // generate the geometry OceanVerts = new VertexPositionNormalTexture[6]; OceanVerts[0] = new VertexPositionNormalTexture(new Vector3(-5000, 0, -5000), new Vector3(0, 1, 0), new Vector2(0, 0)); OceanVerts[1] = new VertexPositionNormalTexture(new Vector3(5000, 0, -5000), new Vector3(0, 1, 0), new Vector2(1, 0)); OceanVerts[2] = new VertexPositionNormalTexture(new Vector3(-5000, 0, 5000), new Vector3(0, 1, 0), new Vector2(0, 1)); OceanVerts[3] = OceanVerts[2]; OceanVerts[4] = OceanVerts[1]; OceanVerts[5] = new VertexPositionNormalTexture(new Vector3(5000, 0, 5000), new Vector3(0, 1, 0), new Vector2(1, 1)); }
/// <summary> /// This is an important function. I have no idea what it does, but it helps /// render body meshes correctly. This function was ported from SimPose 8. /// </summary> /// <param name="TransformedVector1">The first transformed vector.</param> /// <param name="TransformedVector2">The second transformed vector.</param> /// <param name="Target">The target vector.</param> /// <param name="Weight">The weight (last quaternion in a bone's array of quaternions).</param> public void Blend(Vector3 TransformedVector1, Vector3 TransformedVector2, ref VertexPositionNormalTexture Target, float Weight) { float FloatingPointDelta = 0.000001f; float Weight1 = 1.0f - Weight; Target.Position.X = Weight * TransformedVector1.X + Weight1 * Target.Position.X; Target.Position.Y = Weight * TransformedVector1.Y + Weight1 * Target.Position.Y; Target.Position.Z = Weight * TransformedVector1.Z + Weight1 * Target.Position.Z; //Normalize the target's normal. double Length = Math.Sqrt((Target.Normal.X * Target.Normal.X) + (Target.Normal.Y * Target.Normal.Y) + (Target.Normal.Z * Target.Normal.Z)); double Factor = (Math.Abs(Length) > FloatingPointDelta) ? Length : 1.0f; Target.Normal.X /= (float)Factor; Target.Normal.Y /= (float)Factor; Target.Normal.Z /= (float)Factor; }
public void DrawNormals(Model model, Color color, Matrix world, XCamera camera) { X.GraphicsDevice.Indices = null; X.GraphicsDevice.Vertices[0].SetSource(null, 0, 0); foreach (ModelMesh mesh in model.Meshes) { int vertexCount = mesh.VertexBuffer.SizeInBytes / VertexPositionNormalTexture.SizeInBytes; VertexPositionNormalTexture[] verts = new VertexPositionNormalTexture[vertexCount]; mesh.VertexBuffer.GetData(verts); for (int i = 0; i < vertexCount; i++) { DrawLine(verts[i].Position, verts[i].Position + verts[i].Normal, color); } } //Draw(world, camera.View, camera.Projection); }
private void GenerateGeometry() { var UnitZ = new Vector3(0, 0, 1); var verticesPText = new VertexPositionNormalTexture[6]; verticesPText[5] = new VertexPositionNormalTexture(new Vector3(-10, 0, 0), -UnitZ, new Vector2(0, 0)); verticesPText[4] = new VertexPositionNormalTexture(new Vector3(10, 20, 0), -UnitZ, new Vector2(1, 1)); verticesPText[3] = new VertexPositionNormalTexture(new Vector3(-10, 20, 0), -UnitZ, new Vector2(0, 1)); verticesPText[2] = verticesPText[5]; verticesPText[1] = new VertexPositionNormalTexture(new Vector3(10, 0, 0), -UnitZ, new Vector2(1, 0)); verticesPText[0] = verticesPText[4]; }
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); }
private void InitVertices() { vertices = new VertexPositionNormalTexture[6]; Vector3 normal1 = new Vector3(-1, 0, 0); Vector3 normal2 = new Vector3(0, 1, 0); Vector3 sharedNormal = normal1 + normal2; sharedNormal.Normalize(); vertices[0] = new VertexPositionNormalTexture(new Vector3(0, -1, 0), normal1, new Vector2(0, 1)); vertices[1] = new VertexPositionNormalTexture(new Vector3(0, 0, -1), sharedNormal, new Vector2(0.5f, 0)); vertices[2] = new VertexPositionNormalTexture(new Vector3(0, 0, 0), sharedNormal, new Vector2(0.5f, 1)); vertices[3] = new VertexPositionNormalTexture(new Vector3(0, 0, 0), sharedNormal, new Vector2(0.5f, 1)); vertices[4] = new VertexPositionNormalTexture(new Vector3(0, 0, -1), sharedNormal, new Vector2(0.5f, 1)); vertices[5] = new VertexPositionNormalTexture(new Vector3(1, 0, 0), normal2, new Vector2(1, 1)); myVertexDeclaration = new VertexDeclaration(device, VertexPositionNormalTexture.VertexElements); }
public VertexPositionNormalTexture[] getPoints() { VertexPositionNormalTexture[] points = new VertexPositionNormalTexture[vertices.Count]; /*VertexPositionNormalTexture cent = new VertexPositionNormalTexture(); * cent.Normal = plane.getNormal(); * cent.Position = getCenter(); * cent.TextureCoordinate = calcTexCoords(getCenter()); * points[0] = cent;*/ for (int i = 0; i < vertices.Count; i++) { VertexPositionNormalTexture p = new VertexPositionNormalTexture(); p.Position = vertices[i].position; p.Normal = plane.getNormal(); p.TextureCoordinate = vertices[i].texCoord; points[i] = p; } return(points); }
/// <summary> /// Create a single spritesheet step. /// </summary> /// <param name="positionInSpritesheet">Position in spritesheet (0-1 coords).</param> /// <param name="sizeInSpriteSheet">Size in spritesheet (0-1 coords).</param> SpriteSheetStep BuildStep(Vector2 positionInSpritesheet, Vector2 sizeInSpriteSheet) { // create vertices VertexPositionNormalTexture[] vertices = new VertexPositionNormalTexture[4]; // set normal for (int i = 0; i < 4; ++i) { vertices[i].Normal = Vector3.Forward; } // set vertices position and UV float halfSize = 0.5f; vertices[0].Position = new Vector3(-halfSize, -halfSize, 0); // bottom left vertices[1].Position = new Vector3(-halfSize, halfSize, 0); // top left vertices[2].Position = new Vector3(halfSize, -halfSize, 0); // bottom right vertices[3].Position = new Vector3(halfSize, halfSize, 0); // top right // set vertices UVs vertices[0].TextureCoordinate = positionInSpritesheet + sizeInSpriteSheet; // bottom left vertices[1].TextureCoordinate = positionInSpritesheet + new Vector2(sizeInSpriteSheet.X, 0); // top left vertices[2].TextureCoordinate = positionInSpritesheet + new Vector2(0, sizeInSpriteSheet.Y); // bottom right vertices[3].TextureCoordinate = positionInSpritesheet; // top right // Set the index buffer for each vertex, using clockwise winding short[] indexes = new short[6]; indexes[0] = 0; indexes[1] = 1; indexes[2] = 2; indexes[3] = 2; indexes[4] = 1; indexes[5] = 3; // create a new step and add to steps dictionary SpriteSheetStep step = new SpriteSheetStep(); step.Vertices = vertices; step.Indexes = indexes; return(step); }
private static ModelX ReadVersion1(BinaryReader reader) { ModelSubset[] subsets; VertexPositionNormalTexture[] vertices; vertices = new VertexPositionNormalTexture[reader.ReadInt32()]; for (int idx = 0; idx < vertices.Length; ++idx) { Vector3 position = new Vector3(reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle()); Vector3 normal = new Vector3(reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle()); Vector2 coords = new Vector2(reader.ReadSingle(), reader.ReadSingle()); vertices[idx] = new VertexPositionNormalTexture(position, normal, coords); } subsets = new ModelSubset[reader.ReadInt32()]; for (int idx = 0; idx < subsets.Length; ++idx) { subsets[idx] = ModelSubset.Deserialize(reader); } int materialSetsCount = reader.ReadInt32(); int materialsPerSet = reader.ReadInt32(); List <Material[]> materialSets = new List <Material[]>(); for (int idx = 0; idx < materialSetsCount; ++idx) { Material[] materials = new Material[materialsPerSet]; materialSets.Add(materials); for (int idx2 = 0; idx2 < materialsPerSet; ++idx2) { materials[idx2] = Material.Deserialize(reader); } } return(new ModelX(materialSets, subsets, vertices)); }
/// <summary> /// �V�������_��v���~�e�B�u ���f���ɒlj����܂��B����́A /// �������v���Z�X���ɁAInitializePrimitive �̑O�� /// �Ăяo���K�v������܂��B /// </summary> protected void AddVertex(Vector3 position, Vector3 normal, Vector2 vertexCoord) { //vertices.Add(new VertexPositionNormal(position, normal)); var v = new VertexPositionNormalTexture(position, normal, vertexCoord); vertices.Add(v); //vertices.Add(new VertexPositionTexture(position, Vector2.Zero)); }
/// <summary> /// Creates a cube with six faces each one pointing in a different direction. /// </summary> /// <param name="device">The device.</param> /// <param name="size">The size.</param> /// <param name="toLeftHanded">if set to <c>true</c> vertices and indices will be transformed to left handed. Default is true.</param> /// <returns>A cube.</returns> public static GeometricPrimitive New(GraphicsDevice device, float size = 1.0f, bool toLeftHanded = true) { var vertices = new VertexPositionNormalTexture[CubeFaceCount * 4]; var indices = new int[CubeFaceCount * 6]; size /= 2.0f; int vertexCount = 0; int indexCount = 0; // Create each face in turn. for (int i = 0; i < CubeFaceCount; i++) { Vector3 normal = faceNormals[i]; // Get two vectors perpendicular both to the face normal and to each other. Vector3 basis = (i >= 4) ? Vector3.UnitZ : Vector3.UnitY; Vector3 side1; Vector3.Cross(ref normal, ref basis, out side1); Vector3 side2; Vector3.Cross(ref normal, ref side1, out side2); // Six indices (two triangles) per face. int vbase = i * 4; indices[indexCount++] = (vbase + 0); indices[indexCount++] = (vbase + 1); indices[indexCount++] = (vbase + 2); indices[indexCount++] = (vbase + 0); indices[indexCount++] = (vbase + 2); indices[indexCount++] = (vbase + 3); // Four vertices per face. vertices[vertexCount++] = new VertexPositionNormalTexture((normal - side1 - side2) * size, normal, textureCoordinates[0]); vertices[vertexCount++] = new VertexPositionNormalTexture((normal - side1 + side2) * size, normal, textureCoordinates[1]); vertices[vertexCount++] = new VertexPositionNormalTexture((normal + side1 + side2) * size, normal, textureCoordinates[2]); vertices[vertexCount++] = new VertexPositionNormalTexture((normal + side1 - side2) * size, normal, textureCoordinates[3]); } // Create the primitive object. return new GeometricPrimitive(device, vertices, indices, toLeftHanded) { Name = "Cube"}; }
/// <summary> /// Creates a teapot primitive. /// </summary> /// <param name="size">The size.</param> /// <param name="tessellation">The tessellation.</param> /// <param name="vScale"></param> /// <param name="toLeftHanded">if set to <c>true</c> vertices and indices will be transformed to left handed. Default is false.</param> /// <param name="uScale"></param> /// <returns>GeometricPrimitive.</returns> /// <exception cref="System.ArgumentOutOfRangeException">tessellation;tessellation must be > 0</exception> public static GeometricMeshData<VertexPositionNormalTexture> New(float size = 1.0f, int tessellation = 8, float uScale = 1.0f, float vScale = 1.0f, bool toLeftHanded = false) { var vertices = new List<VertexPositionNormalTexture>(); var indices = new List<int>(); if (tessellation < 1) tessellation = 1; var scaleVector = new Vector3(size, size, size); var scaleNegateX = scaleVector; scaleNegateX.X = -scaleNegateX.X; var scaleNegateZ = scaleVector; scaleNegateZ.Z = -scaleNegateZ.Z; var scaleNegateXZ = new Vector3(-size, size, -size); for (int i = 0; i < TeapotPatches.Length; i++) { var patch = TeapotPatches[i]; // Because the teapot is symmetrical from left to right, we only store // data for one side, then tessellate each patch twice, mirroring in X. TessellatePatch(vertices, indices, ref patch, tessellation, scaleVector, false); TessellatePatch(vertices, indices, ref patch, tessellation, scaleNegateX, true); if (patch.mirrorZ) { // Some parts of the teapot (the body, lid, and rim, but not the // handle or spout) are also symmetrical from front to back, so // we tessellate them four times, mirroring in Z as well as X. TessellatePatch(vertices, indices, ref patch, tessellation, scaleNegateZ, true); TessellatePatch(vertices, indices, ref patch, tessellation, scaleNegateXZ, false); } } var texCoord = new Vector2(uScale, vScale); for (var i = 0; i < vertices.Count; i++) { vertices[i] = new VertexPositionNormalTexture(vertices[i].Position, vertices[i].Normal, vertices[i].TextureCoordinate*texCoord); } return new GeometricMeshData<VertexPositionNormalTexture>(vertices.ToArray(), indices.ToArray(), toLeftHanded) { Name = "Teapot" }; }
/// <summary> /// Creates a Plane primitive on the X/Y plane with a normal equal to -<see cref="Vector3.UnitZ"/>. /// </summary> /// <param name="sizeX">The size X.</param> /// <param name="sizeY">The size Y.</param> /// <param name="tessellationX">The tessellation, as the number of quads per X axis.</param> /// <param name="tessellationY">The tessellation, as the number of quads per Y axis.</param> /// <param name="toLeftHanded">if set to <c>true</c> vertices and indices will be transformed to left handed. Default is false.</param> /// <param name="uFactor">Scale U coordinates between 0 and the values of this parameter.</param> /// <param name="vFactor">Scale V coordinates 0 and the values of this parameter.</param> /// <param name="generateBackFace">Add a back face to the plane</param> /// <returns>A Plane primitive.</returns> /// <exception cref="System.ArgumentOutOfRangeException">tessellation;tessellation must be > 0</exception> public static GeometricMeshData<VertexPositionNormalTexture> New(float sizeX = 1.0f, float sizeY = 1.0f, int tessellationX = 1, int tessellationY = 1, float uFactor = 1f, float vFactor = 1f, bool generateBackFace = false, bool toLeftHanded = false) { if (tessellationX < 1) tessellationX = 1; if (tessellationY < 1) tessellationY = 1; var lineWidth = tessellationX + 1; var lineHeight = tessellationY + 1; var vertices = new VertexPositionNormalTexture[lineWidth * lineHeight * (generateBackFace? 2: 1)]; var indices = new int[tessellationX * tessellationY * 6 * (generateBackFace? 2: 1)]; var deltaX = sizeX / tessellationX; var deltaY = sizeY / tessellationY; sizeX /= 2.0f; sizeY /= 2.0f; int vertexCount = 0; int indexCount = 0; var normal = Vector3.UnitZ; var uv = new Vector2(uFactor, vFactor); // Create vertices for (int y = 0; y < (tessellationY + 1); y++) { for (int x = 0; x < (tessellationX + 1); x++) { var position = new Vector3(-sizeX + deltaX * x, sizeY - deltaY * y, 0); var texCoord = new Vector2(uv.X * x / tessellationX, uv.Y * y / tessellationY); vertices[vertexCount++] = new VertexPositionNormalTexture(position, normal, texCoord); } } // Create indices for (int y = 0; y < tessellationY; y++) { for (int x = 0; x < tessellationX; x++) { // Six indices (two triangles) per face. int vbase = lineWidth * y + x; indices[indexCount++] = (vbase + 1); indices[indexCount++] = (vbase + 1 + lineWidth); indices[indexCount++] = (vbase + lineWidth); indices[indexCount++] = (vbase + 1); indices[indexCount++] = (vbase + lineWidth); indices[indexCount++] = (vbase); } } if(generateBackFace) { normal = -Vector3.UnitZ; for (int y = 0; y < (tessellationY + 1); y++) { for (int x = 0; x < (tessellationX + 1); x++) { var position = new Vector3(-sizeX + deltaX * x, sizeY - deltaY * y, 0); var texCoord = new Vector2(uv.X * x / tessellationX, uv.Y * y / tessellationY); vertices[vertexCount++] = new VertexPositionNormalTexture(position, normal, texCoord); } } // Create indices for (int y = 0; y < tessellationY; y++) { for (int x = 0; x < tessellationX; x++) { // Six indices (two triangles) per face. int vbase = lineWidth * (y + tessellationY + 1) + x; indices[indexCount++] = (vbase + 1); indices[indexCount++] = (vbase + lineWidth); indices[indexCount++] = (vbase + 1 + lineWidth); indices[indexCount++] = (vbase + 1); indices[indexCount++] = (vbase); indices[indexCount++] = (vbase + lineWidth); } } } // Create the primitive object. return new GeometricMeshData<VertexPositionNormalTexture>(vertices, indices, toLeftHanded) { Name = "Plane" }; }
/// <summary> /// Creates a sphere primitive. /// </summary> /// <param name="length">The length of the capsule. That is the distance between the two sphere centers.</param> /// <param name="radius">The radius of the capsule.</param> /// <param name="tessellation">The tessellation.</param> /// <param name="vScale"></param> /// <param name="toLeftHanded">if set to <c>true</c> vertices and indices will be transformed to left handed. Default is false.</param> /// <param name="uScale"></param> /// <returns>A sphere primitive.</returns> /// <exception cref="System.ArgumentOutOfRangeException">tessellation;Must be >= 3</exception> public static GeometricMeshData<VertexPositionNormalTexture> New(float length = 1.0f, float radius = 0.5f, int tessellation = 8, float uScale = 1.0f, float vScale = 1.0f, bool toLeftHanded = false) { if (tessellation < 3) tessellation = 3; int verticalSegments = 2 * tessellation; int horizontalSegments = 4 * tessellation; var vertices = new VertexPositionNormalTexture[verticalSegments * (horizontalSegments + 1)]; var indices = new int[(verticalSegments-1) * (horizontalSegments + 1) * 6]; var vertexCount = 0; // Create rings of vertices at progressively higher latitudes. for (int i = 0; i < verticalSegments; i++) { float v; float deltaY; float latitude; if (i < verticalSegments / 2) { deltaY = -length / 2; v = 1.0f - (0.25f * i / (tessellation - 1)); latitude = (float)((i * Math.PI / (verticalSegments-2)) - Math.PI / 2.0); } else { deltaY = length / 2; v = 0.5f - (0.25f * (i - 1) / (tessellation - 1)); latitude = (float)(((i - 1) * Math.PI / (verticalSegments - 2)) - Math.PI / 2.0); } var dy = (float)Math.Sin(latitude); var dxz = (float)Math.Cos(latitude); // Create a single ring of vertices at this latitude. for (int j = 0; j <= horizontalSegments; j++) { float u = (float)j / horizontalSegments; var longitude = (float)(j * 2.0 * Math.PI / horizontalSegments); var dx = (float)Math.Sin(longitude); var dz = (float)Math.Cos(longitude); dx *= dxz; dz *= dxz; var normal = new Vector3(dx, dy, dz); var textureCoordinate = new Vector2(u * uScale, v * vScale); var position = radius * normal + new Vector3(0, deltaY, 0); vertices[vertexCount++] = new VertexPositionNormalTexture(position, normal, textureCoordinate); } } // Fill the index buffer with triangles joining each pair of latitude rings. int stride = horizontalSegments + 1; int indexCount = 0; for (int i = 0; i < verticalSegments-1; i++) { for (int j = 0; j <= horizontalSegments; j++) { int nextI = i + 1; int nextJ = (j + 1) % stride; indices[indexCount++] = (i * stride + j); indices[indexCount++] = (nextI * stride + j); indices[indexCount++] = (i * stride + nextJ); indices[indexCount++] = (i * stride + nextJ); indices[indexCount++] = (nextI * stride + j); indices[indexCount++] = (nextI * stride + nextJ); } } // Create the primitive object. // Create the primitive object. return new GeometricMeshData<VertexPositionNormalTexture>(vertices, indices, toLeftHanded) { Name = "Capsule" }; }
public void LoadMesh(AssimpSharp.Mesh mesh) { var vertexSource = new VertexPositionNormalTexture[mesh.Vertices.Length]; for (int i = 0; i < mesh.Vertices.Length; i++) { vertexSource[i].Position = mesh.Vertices[i]; vertexSource[i].Normal = mesh.Normals[i]; vertexSource[i].TextureCoordinate = Vector2.Zero; } if (mesh.HasTextureCoords(0)) { var channel = mesh.TextureCoords[0]; for(int i=0; i<channel.Length; i++) { vertexSource[i].TextureCoordinate.X = channel[i].X; vertexSource[i].TextureCoordinate.Y = 1 - channel[i].Y; } } var vbd = new BufferDescription() { BindFlags = BindFlags.VertexBuffer, CpuAccessFlags = CpuAccessFlags.None, OptionFlags = ResourceOptionFlags.None, SizeInBytes = VertexPositionNormalTexture.Size * vertexSource.Length, Usage = ResourceUsage.Default, StructureByteStride = VertexPositionNormalTexture.Size, }; vertices = Buffer.Create(device, vertexSource, vbd); var indexSource = new List<int>(); for(int i=0; i<mesh.Faces.Length; i++) { var face = mesh.Faces[i]; if (face.Indices.Length == 3) { indexSource.AddRange(face.Indices.Reverse()); } else if (face.Indices.Length == 4) { indexSource.Add(face.Indices[2]); indexSource.Add(face.Indices[1]); indexSource.Add(face.Indices[0]); indexSource.Add(face.Indices[0]); indexSource.Add(face.Indices[3]); indexSource.Add(face.Indices[2]); } else if (face.Indices.Length == 5) { indexSource.Add(face.Indices[2]); indexSource.Add(face.Indices[1]); indexSource.Add(face.Indices[0]); indexSource.Add(face.Indices[0]); indexSource.Add(face.Indices[3]); indexSource.Add(face.Indices[2]); indexSource.Add(face.Indices[0]); indexSource.Add(face.Indices[4]); indexSource.Add(face.Indices[3]); } else { throw (new Exception("invalid vertex count of polygon")); } } var ibd = new BufferDescription() { BindFlags = BindFlags.IndexBuffer, CpuAccessFlags = CpuAccessFlags.None, OptionFlags = ResourceOptionFlags.None, SizeInBytes = Utilities.SizeOf<int>() * indexSource.Count, Usage = ResourceUsage.Default, StructureByteStride = Utilities.SizeOf<int>(), }; indices = Buffer.Create(device, indexSource.ToArray(), ibd); indexCount = indexSource.Count; }
/// <summary> /// Creates a cone a circular base and a rolled face. /// </summary> /// <param name="radius">The radius or the base</param> /// <param name="height">The height of the cone</param> /// <param name="tessellation">The number of segments composing the base</param> /// <param name="toLeftHanded">if set to <c>true</c> vertices and indices will be transformed to left handed. Default is false.</param> /// <returns>A cone.</returns> public static GeometricMeshData<VertexPositionNormalTexture> New(float radius = 0.5f, float height = 1.0f, int tessellation = 16, bool toLeftHanded = false) { if (tessellation < 3) tessellation = 3; var numberOfSections = tessellation + 1; var vertexNumberBySection = tessellation + 1; var indices = new int[2*tessellation*(2*(tessellation-1)+1)*3]; var vertices = new VertexPositionNormalTexture[2 * vertexNumberBySection * numberOfSections]; var index = 0; var vertice = 0; // e == 0 => Cone // e == 1 => Cap for (var e = 0; e < 2; e++) { var topHeight = e == 0 ? height : 0; var normalSign = Math.Sign(0.5 - e); var slopeLength = Math.Sqrt(radius * radius + topHeight * topHeight); var slopeCos = topHeight / slopeLength; var slopeSin = radius / slopeLength; // the cone sections for (var j = 0; j < tessellation; ++j) { var sectionRatio = j / (float)tessellation; var sectionHeight = sectionRatio * topHeight; var sectionRadius = (1 - sectionRatio) * radius; for (var i = 0; i <= tessellation; ++i) { var angle = i / (double)tessellation * 2.0 * Math.PI; var textureCoordinate = new Vector2((float)i / tessellation, 1 - sectionRatio); var position = new Vector3((float)Math.Cos(angle) * sectionRadius, sectionHeight, (float)Math.Sin(angle) * sectionRadius); var normal = normalSign * new Vector3((float)(Math.Cos(angle) * slopeCos), (float)slopeSin, (float)(Math.Sin(angle) * slopeCos)); vertices[vertice++] = new VertexPositionNormalTexture { Position = position, Normal = normal, TextureCoordinate = textureCoordinate }; } } // the extremity points for (var i = 0; i <= tessellation; ++i) { var position = new Vector3(0, topHeight, 0); var angle = (i + 0.5) / tessellation * 2.0 * Math.PI; var textureCoordinate = new Vector2((i + 0.5f) / tessellation, 0); var normal = normalSign * new Vector3((float)(Math.Cos(angle) * slopeCos), (float)slopeSin, (float)(Math.Sin(angle) * slopeCos)); vertices[vertice++] = new VertexPositionNormalTexture { Position = position, Normal = normal, TextureCoordinate = textureCoordinate }; } } // the indices for (var e = 0; e < 2; e++) { var globalOffset = (e == 0) ? 0 : vertexNumberBySection * numberOfSections; var offsetV1 = (e == 0) ? 1 : vertexNumberBySection; var offsetV2 = (e == 0) ? vertexNumberBySection : 1; var offsetV3 = (e == 0) ? 1 : vertexNumberBySection + 1; var offsetV4 = (e == 0) ? vertexNumberBySection + 1 : 1; // the sections for (var j = 0; j < tessellation-1; ++j) { for (int i = 0; i < tessellation; ++i) { indices[index++] = globalOffset + j * vertexNumberBySection + i; indices[index++] = globalOffset + j * vertexNumberBySection + i + offsetV1; indices[index++] = globalOffset + j * vertexNumberBySection + i + offsetV2; indices[index++] = globalOffset + j * vertexNumberBySection + i + vertexNumberBySection; indices[index++] = globalOffset + j * vertexNumberBySection + i + offsetV3; indices[index++] = globalOffset + j * vertexNumberBySection + i + offsetV4; } } // the extremity triangle for (int i = 0; i < tessellation; ++i) { indices[index++] = globalOffset + (tessellation-1) * vertexNumberBySection + i; indices[index++] = globalOffset + (tessellation-1) * vertexNumberBySection + i + offsetV1; indices[index++] = globalOffset + (tessellation-1) * vertexNumberBySection + i + offsetV2; } } return new GeometricMeshData<VertexPositionNormalTexture>(vertices, indices, toLeftHanded) { Name = "Cone" }; }
/// <summary> /// Fills the color type buffer (VertexPositionColor) /// </summary> /// <param name="points">The points.</param> /// <param name="primitiveType">Type of the primitive.</param> public override void FillColor(List<PointF> points, GeometryPrimitiveType primitiveType) { SetPrimitiveCount(primitiveType, points.Count); VertexPositionNormalTexture[] vertex = new VertexPositionNormalTexture[points.Count]; for (int i = 0; i < points.Count; i++) { vertex[i] = new VertexPositionNormalTexture(new Vector3(points[i].X, points[i].Y, 0), new Vector3(0, 0, 1), Vector2.Zero); } VertexBuffer = VertexBuffer.Vertex.New(XenkoRenderer.GraphicsDevice, vertex); VertexBuffer.Reload = (graphicsResource) => ((VertexBuffer)graphicsResource).Recreate(vertex); VertexBufferBinding = new VertexBufferBinding(VertexBuffer, VertexPositionNormalTexture.Layout, vertex.Length, VertexPositionNormalTexture.Size); InputElementDescriptions = VertexBufferBinding.Declaration.CreateInputElements(); }
/// <summary> /// Creates a Plane primitive on the X/Y plane with a normal equal to -<see cref="Vector3.UnitZ"/>. /// </summary> /// <param name="sizeX">The size X.</param> /// <param name="sizeY">The size Y.</param> /// <param name="tessellationX">The tessellation, as the number of quads per X axis.</param> /// <param name="tessellationY">The tessellation, as the number of quads per Y axis.</param> /// <param name="toLeftHanded">if set to <c>true</c> vertices and indices will be transformed to left handed. Default is false.</param> /// <param name="uFactor">Scale U coordinates between 0 and the values of this parameter.</param> /// <param name="vFactor">Scale V coordinates 0 and the values of this parameter.</param> /// <param name="generateBackFace">Add a back face to the plane</param> /// <param name="normalDirection">The direction of the plane normal</param> /// <returns>A Plane primitive.</returns> /// <exception cref="System.ArgumentOutOfRangeException">tessellation;tessellation must be > 0</exception> public static GeometricMeshData<VertexPositionNormalTexture> New(float sizeX = 1.0f, float sizeY = 1.0f, int tessellationX = 1, int tessellationY = 1, float uFactor = 1f, float vFactor = 1f, bool generateBackFace = false, bool toLeftHanded = false, NormalDirection normalDirection = 0) { if (tessellationX < 1) tessellationX = 1; if (tessellationY < 1) tessellationY = 1; var lineWidth = tessellationX + 1; var lineHeight = tessellationY + 1; var vertices = new VertexPositionNormalTexture[lineWidth * lineHeight * (generateBackFace? 2: 1)]; var indices = new int[tessellationX * tessellationY * 6 * (generateBackFace? 2: 1)]; var deltaX = sizeX / tessellationX; var deltaY = sizeY / tessellationY; sizeX /= 2.0f; sizeY /= 2.0f; int vertexCount = 0; int indexCount = 0; Vector3 normal; switch (normalDirection) { default: case NormalDirection.UpZ: normal = Vector3.UnitZ; break; case NormalDirection.UpY: normal = Vector3.UnitY; break; case NormalDirection.UpX: normal = Vector3.UnitX; break; } var uv = new Vector2(uFactor, vFactor); // Create vertices for (int y = 0; y < (tessellationY + 1); y++) { for (int x = 0; x < (tessellationX + 1); x++) { Vector3 position; switch (normalDirection) { default: case NormalDirection.UpZ: position = new Vector3(-sizeX + deltaX * x, sizeY - deltaY * y, 0); break; case NormalDirection.UpY: position = new Vector3(-sizeX + deltaX * x, 0, -sizeY + deltaY * y); break; case NormalDirection.UpX: position = new Vector3(0, sizeY - deltaY * y, sizeX - deltaX * x); break; } var texCoord = new Vector2(uv.X * x / tessellationX, uv.Y * y / tessellationY); vertices[vertexCount++] = new VertexPositionNormalTexture(position, normal, texCoord); } } // Create indices for (int y = 0; y < tessellationY; y++) { for (int x = 0; x < tessellationX; x++) { // Six indices (two triangles) per face. int vbase = lineWidth * y + x; indices[indexCount++] = (vbase + 1); indices[indexCount++] = (vbase + 1 + lineWidth); indices[indexCount++] = (vbase + lineWidth); indices[indexCount++] = (vbase + 1); indices[indexCount++] = (vbase + lineWidth); indices[indexCount++] = (vbase); } } if(generateBackFace) { var numVertices = lineWidth * lineHeight; normal = -normal; for (int y = 0; y < (tessellationY + 1); y++) { for (int x = 0; x < (tessellationX + 1); x++) { var baseVertex = vertices[vertexCount - numVertices]; var position = new Vector3(baseVertex.Position.X, baseVertex.Position.Y, baseVertex.Position.Z); var texCoord = new Vector2(uv.X * x / tessellationX, uv.Y * y / tessellationY); vertices[vertexCount++] = new VertexPositionNormalTexture(position, normal, texCoord); } } // Create indices for (int y = 0; y < tessellationY; y++) { for (int x = 0; x < tessellationX; x++) { // Six indices (two triangles) per face. int vbase = lineWidth * (y + tessellationY + 1) + x; indices[indexCount++] = (vbase + 1); indices[indexCount++] = (vbase + lineWidth); indices[indexCount++] = (vbase + 1 + lineWidth); indices[indexCount++] = (vbase + 1); indices[indexCount++] = (vbase); indices[indexCount++] = (vbase + lineWidth); } } } // Create the primitive object. return new GeometricMeshData<VertexPositionNormalTexture>(vertices, indices, toLeftHanded) { Name = "Plane" }; }
void LoadFromOBJFile(string filename) { var file = new StreamReader(filename); var directory = Path.GetDirectoryName(filename); var positions = new List<Vector4>(); var textureCoords = new List<Vector2>(); var normals = new List<Vector3>(); Subset subset = null; while (true) { string nextLine = file.ReadLine(); if (nextLine == null) // end of file break; var terms = nextLine.Split(new char[] { ' ', '\t' }, StringSplitOptions.RemoveEmptyEntries); if (terms.Length == 0) // empty line continue; var command = terms[0]; if (command == "#" || command == "") { // comment } else if (command == "v") // position { float x = float.Parse(terms[1]); float y = float.Parse(terms[2]); float z = float.Parse(terms[3]); positions.Add(new Vector4(x, y, z, 1)); } else if (command == "vt") // texture coord { float u = float.Parse(terms[1]); float v = float.Parse(terms[2]); textureCoords.Add(new Vector2(u, v)); } else if (command == "vn") // normal { float x = float.Parse(terms[1]); float y = float.Parse(terms[2]); float z = float.Parse(terms[3]); normals.Add(new Vector3(x, y, z)); } else if (command == "f") // face { for (int i = 0; i < 3; i++) { // TODO: suppoprt relative (negative) indices var indices = terms[1 + i].Split('/'); var vertex = new VertexPositionNormalTexture(); vertex.position = positions[int.Parse(indices[0]) - 1]; // OBJ indices are 1-based if (indices[1] != "") // optional texture coords vertex.texture = textureCoords[int.Parse(indices[1]) - 1]; if (indices[2] != "") // optional normal vertex.normal = normals[int.Parse(indices[2]) - 1]; vertices.Add(vertex); subset.length++; } } else if (command == "mtllib") // .mtl file reference { LoadMTLFile(directory + "/" + terms[1]); } else if (command == "usemtl") // material { var name = terms[1]; Material material = null; if (materials.ContainsKey(name)) material = materials[name]; else { material = new Material(); materials.Add(name, material); } subset = new Subset(); subset.material = material; subset.start = vertices.Count; // next vertex to be created subsets.Add(subset); } else { // unimplemented or unrecognized command } } file.Close(); }
/// <summary> /// Create a cube with one texture for all faces. /// </summary> /// <param name="texturePath">Texture file to use.</param> /// <param name="size">Size of cube.</param> /// <returns>A textured cube.</returns> public MyModel CreateTexturedCube(String texturePath, Vector3 size) { VertexPositionNormalTexture[] shapeArray = new VertexPositionNormalTexture[]{ new VertexPositionNormalTexture(new Vector3(-1.0f, -1.0f, -1.0f), -Vector3.UnitZ, new Vector2(0.0f, 1.0f)), // Front new VertexPositionNormalTexture(new Vector3(-1.0f, 1.0f, -1.0f), -Vector3.UnitZ, new Vector2(0.0f, 0.0f)), new VertexPositionNormalTexture(new Vector3(1.0f, 1.0f, -1.0f), -Vector3.UnitZ, new Vector2(1.0f, 0.0f)), new VertexPositionNormalTexture(new Vector3(-1.0f, -1.0f, -1.0f), -Vector3.UnitZ, new Vector2(0.0f, 1.0f)), new VertexPositionNormalTexture(new Vector3(1.0f, 1.0f, -1.0f), -Vector3.UnitZ, new Vector2(1.0f, 0.0f)), new VertexPositionNormalTexture(new Vector3(1.0f, -1.0f, -1.0f), -Vector3.UnitZ, new Vector2(1.0f, 1.0f)), new VertexPositionNormalTexture(new Vector3(-1.0f, -1.0f, 1.0f), Vector3.UnitZ, new Vector2(1.0f, 1.0f)), // BACK new VertexPositionNormalTexture(new Vector3(1.0f, 1.0f, 1.0f), Vector3.UnitZ, new Vector2(0.0f, 0.0f)), new VertexPositionNormalTexture(new Vector3(-1.0f, 1.0f, 1.0f), Vector3.UnitZ, new Vector2(1.0f, 0.0f)), new VertexPositionNormalTexture(new Vector3(-1.0f, -1.0f, 1.0f), Vector3.UnitZ, new Vector2(1.0f, 1.0f)), new VertexPositionNormalTexture(new Vector3(1.0f, -1.0f, 1.0f), Vector3.UnitZ, new Vector2(0.0f, 1.0f)), new VertexPositionNormalTexture(new Vector3(1.0f, 1.0f, 1.0f), Vector3.UnitZ, new Vector2(0.0f, 0.0f)), new VertexPositionNormalTexture(new Vector3(-1.0f, 1.0f, -1.0f), Vector3.UnitY, new Vector2(0.0f, 1.0f)), // Top new VertexPositionNormalTexture(new Vector3(-1.0f, 1.0f, 1.0f), Vector3.UnitY, new Vector2(0.0f, 0.0f)), new VertexPositionNormalTexture(new Vector3(1.0f, 1.0f, 1.0f), Vector3.UnitY, new Vector2(1.0f, 0.0f)), new VertexPositionNormalTexture(new Vector3(-1.0f, 1.0f, -1.0f), Vector3.UnitY, new Vector2(0.0f, 1.0f)), new VertexPositionNormalTexture(new Vector3(1.0f, 1.0f, 1.0f), Vector3.UnitY, new Vector2(1.0f, 0.0f)), new VertexPositionNormalTexture(new Vector3(1.0f, 1.0f, -1.0f), Vector3.UnitY, new Vector2(1.0f, 1.0f)), new VertexPositionNormalTexture(new Vector3(-1.0f, -1.0f, -1.0f), -Vector3.UnitY, new Vector2(0.0f, 0.0f)), // Bottom new VertexPositionNormalTexture(new Vector3(1.0f, -1.0f, 1.0f), -Vector3.UnitY, new Vector2(1.0f, 1.0f)), new VertexPositionNormalTexture(new Vector3(-1.0f, -1.0f, 1.0f), -Vector3.UnitY, new Vector2(0.0f, 1.0f)), new VertexPositionNormalTexture(new Vector3(-1.0f, -1.0f, -1.0f), -Vector3.UnitY, new Vector2(0.0f, 0.0f)), new VertexPositionNormalTexture(new Vector3(1.0f, -1.0f, -1.0f), -Vector3.UnitY, new Vector2(1.0f, 0.0f)), new VertexPositionNormalTexture(new Vector3(1.0f, -1.0f, 1.0f), -Vector3.UnitY, new Vector2(1.0f, 1.0f)), new VertexPositionNormalTexture(new Vector3(-1.0f, -1.0f, -1.0f), -Vector3.UnitX, new Vector2(1.0f, 1.0f)), // Left new VertexPositionNormalTexture(new Vector3(-1.0f, -1.0f, 1.0f), -Vector3.UnitX, new Vector2(0.0f, 1.0f)), new VertexPositionNormalTexture(new Vector3(-1.0f, 1.0f, 1.0f), -Vector3.UnitX, new Vector2(0.0f, 0.0f)), new VertexPositionNormalTexture(new Vector3(-1.0f, -1.0f, -1.0f), -Vector3.UnitX, new Vector2(1.0f, 1.0f)), new VertexPositionNormalTexture(new Vector3(-1.0f, 1.0f, 1.0f), -Vector3.UnitX, new Vector2(0.0f, 0.0f)), new VertexPositionNormalTexture(new Vector3(-1.0f, 1.0f, -1.0f), -Vector3.UnitX, new Vector2(1.0f, 0.0f)), new VertexPositionNormalTexture(new Vector3(1.0f, -1.0f, -1.0f), Vector3.UnitX, new Vector2(0.0f, 1.0f)), // Right new VertexPositionNormalTexture(new Vector3(1.0f, 1.0f, 1.0f), Vector3.UnitX, new Vector2(1.0f, 0.0f)), new VertexPositionNormalTexture(new Vector3(1.0f, -1.0f, 1.0f), Vector3.UnitX, new Vector2(1.0f, 1.0f)), new VertexPositionNormalTexture(new Vector3(1.0f, -1.0f, -1.0f), Vector3.UnitX, new Vector2(0.0f, 1.0f)), new VertexPositionNormalTexture(new Vector3(1.0f, 1.0f, -1.0f), Vector3.UnitX, new Vector2(0.0f, 0.0f)), new VertexPositionNormalTexture(new Vector3(1.0f, 1.0f, 1.0f), Vector3.UnitX, new Vector2(1.0f, 0.0f)), }; for (int i = 0; i < shapeArray.Length; i++) { shapeArray[i].Position.X *= size.X / 2; shapeArray[i].Position.Y *= size.Y / 2; shapeArray[i].Position.Z *= size.Z / 2; } float collisionRadius = (size.X + size.Y + size.Z) / 6 ; return new MyModel(game, shapeArray, texturePath, collisionRadius); }
/// <summary> /// Creates a sphere primitive. /// </summary> /// <param name="diameter">The diameter.</param> /// <param name="tessellation">The tessellation.</param> /// <param name="uScale">The u scale.</param> /// <param name="vScale">The v scale.</param> /// <param name="toLeftHanded">if set to <c>true</c> vertices and indices will be transformed to left handed. Default is false.</param> /// <returns>A sphere primitive.</returns> /// <exception cref="System.ArgumentOutOfRangeException">tessellation;Must be >= 3</exception> public static GeometricMeshData<VertexPositionNormalTexture> New(float diameter = 1.0f, int tessellation = 16, float uScale = 1.0f, float vScale = 1.0f, bool toLeftHanded = false) { if (tessellation < 3) tessellation = 3; int verticalSegments = tessellation; int horizontalSegments = tessellation * 2; var vertices = new VertexPositionNormalTexture[(verticalSegments + 1) * (horizontalSegments + 1)]; var indices = new int[(verticalSegments) * (horizontalSegments + 1) * 6]; float radius = diameter / 2; int vertexCount = 0; // generate the first extremity points for (int j = 0; j <= horizontalSegments; j++) { var normal = new Vector3(0, -1, 0); var textureCoordinate = new Vector2(uScale * j / (float)horizontalSegments, vScale); vertices[vertexCount++] = new VertexPositionNormalTexture(normal * radius, normal, textureCoordinate); } // Create rings of vertices at progressively higher latitudes. for (int i = 1; i < verticalSegments; i++) { float v = vScale * (1.0f - (float)i / verticalSegments); var latitude = (float)((i * Math.PI / verticalSegments) - Math.PI / 2.0); var dy = (float)Math.Sin(latitude); var dxz = (float)Math.Cos(latitude); // the first point var firstNormal = new Vector3(0, dy, dxz); var firstHorizontalVertex = new VertexPositionNormalTexture(firstNormal * radius, firstNormal, new Vector2(0, v)); vertices[vertexCount++] = firstHorizontalVertex; // Create a single ring of vertices at this latitude. for (int j = 1; j < horizontalSegments; j++) { float u = (uScale * j) / horizontalSegments; var longitude = (float)(j * 2.0 * Math.PI / horizontalSegments); var dx = (float)Math.Sin(longitude); var dz = (float)Math.Cos(longitude); dx *= dxz; dz *= dxz; var normal = new Vector3(dx, dy, dz); var textureCoordinate = new Vector2(u, v); vertices[vertexCount++] = new VertexPositionNormalTexture(normal * radius, normal, textureCoordinate); } // the last point equal to the first point firstHorizontalVertex.TextureCoordinate = new Vector2(uScale, v); vertices[vertexCount++] = firstHorizontalVertex; } // generate the end extremity points for (int j = 0; j <= horizontalSegments; j++) { var normal = new Vector3(0, 1, 0); var textureCoordinate = new Vector2(uScale * j / (float)horizontalSegments, 0f); vertices[vertexCount++] = new VertexPositionNormalTexture(normal * radius, normal, textureCoordinate); } // Fill the index buffer with triangles joining each pair of latitude rings. int stride = horizontalSegments + 1; int indexCount = 0; for (int i = 0; i < verticalSegments; i++) { for (int j = 0; j <= horizontalSegments; j++) { int nextI = i + 1; int nextJ = (j + 1) % stride; indices[indexCount++] = (i * stride + j); indices[indexCount++] = (nextI * stride + j); indices[indexCount++] = (i * stride + nextJ); indices[indexCount++] = (i * stride + nextJ); indices[indexCount++] = (nextI * stride + j); indices[indexCount++] = (nextI * stride + nextJ); } } // Create the primitive object. return new GeometricMeshData<VertexPositionNormalTexture>(vertices, indices, toLeftHanded) {Name = "Sphere"}; }
/// <summary> /// Creates a sphere primitive. /// </summary> /// <param name="device">The device.</param> /// <param name="diameter">The diameter.</param> /// <param name="tessellation">The tessellation.</param> /// <param name="toLeftHanded">if set to <c>true</c> vertices and indices will be transformed to left handed. Default is true.</param> /// <returns>A sphere primitive.</returns> /// <exception cref="System.ArgumentOutOfRangeException">tessellation;Must be >= 3</exception> public static GeometricPrimitive New(GraphicsDevice device, float diameter = 1.0f, int tessellation = 16, bool toLeftHanded = false) { if (tessellation < 3) throw new ArgumentOutOfRangeException("tessellation", "Must be >= 3"); int verticalSegments = tessellation; int horizontalSegments = tessellation * 2; var vertices = new VertexPositionNormalTexture[(verticalSegments + 1) * (horizontalSegments + 1)]; var indices = new int[(verticalSegments) * (horizontalSegments + 1) * 6]; float radius = diameter / 2; int vertexCount = 0; // Create rings of vertices at progressively higher latitudes. for (int i = 0; i <= verticalSegments; i++) { float v = 1.0f - (float)i / verticalSegments; var latitude = (float)((i * Math.PI / verticalSegments) - Math.PI / 2.0); var dy = (float)Math.Sin(latitude); var dxz = (float)Math.Cos(latitude); // Create a single ring of vertices at this latitude. for (int j = 0; j <= horizontalSegments; j++) { float u = (float)j / horizontalSegments; var longitude = (float)(j * 2.0 * Math.PI / horizontalSegments); var dx = (float)Math.Sin(longitude); var dz = (float)Math.Cos(longitude); dx *= dxz; dz *= dxz; var normal = new Vector3(dx, dy, dz); var textureCoordinate = new Vector2(u, v); vertices[vertexCount++] = new VertexPositionNormalTexture(normal * radius, normal, textureCoordinate); } } // Fill the index buffer with triangles joining each pair of latitude rings. int stride = horizontalSegments + 1; int indexCount = 0; for (int i = 0; i < verticalSegments; i++) { for (int j = 0; j <= horizontalSegments; j++) { int nextI = i + 1; int nextJ = (j + 1) % stride; indices[indexCount++] = (i * stride + j); indices[indexCount++] = (nextI * stride + j); indices[indexCount++] = (i * stride + nextJ); indices[indexCount++] = (i * stride + nextJ); indices[indexCount++] = (nextI * stride + j); indices[indexCount++] = (nextI * stride + nextJ); } } // Create the primitive object. return new GeometricPrimitive(device, vertices, indices, toLeftHanded) { Name = "Sphere" }; }
private unsafe void InitializeGraphics(GraphicsDevice graphicsDevice) { var colorBitmap = new Bitmap(gridlet.XLength, gridlet.YLength, PixelFormat.Format32bppRgb); var bitmapData = colorBitmap.LockBits(new System.Drawing.Rectangle(0, 0, gridlet.XLength, gridlet.YLength), ImageLockMode.WriteOnly, PixelFormat.Format32bppRgb); var pScan0 = (byte*)bitmapData.Scan0; for (var y = 0; y < gridlet.YLength; y++) { var pCurrentPixel = pScan0 + bitmapData.Stride * y; for (var x = 0; x < gridlet.XLength; x++) { var cell = gridlet.Cells[x + gridlet.XLength * y]; uint color = 0xEFEFEF; if (cell.Flags.HasFlag(CellFlags.Debug)) { color = 0x0000FF; } else if (cell.Flags.HasFlag(CellFlags.Connector)) { color = 0xFF7F00; } else if (cell.Flags.HasFlag(CellFlags.Edge)) { color = 0x00FF00; } else if (cell.Flags.HasFlag(CellFlags.Blocked)) { color = 0xFF0000; } *(uint*)pCurrentPixel = color; pCurrentPixel += 4; } } colorBitmap.UnlockBits(bitmapData); var ms = new MemoryStream(); colorBitmap.Save(ms, ImageFormat.Bmp); ms.Position = 0; var image = SharpDX.Toolkit.Graphics.Image.Load(ms); // debugTexture = Texture2D.Load(graphicsDevice, @"E:\lolmodprojects\Project Master Yi\masteryi_base_r_cas_shockwave.dds"); debugTexture = Texture2D.New(graphicsDevice, image); var vertices = new VertexPositionNormalTexture[gridlet.XLength * gridlet.YLength * 4]; var indices = new int[gridlet.XLength * gridlet.YLength * 6 + (gridlet.XLength - 1) * (gridlet.YLength - 1) * 12]; int ibOffsetBase = 0; var xOffset = -gridlet.XLength / 2.0f; var yOffset = -gridlet.YLength / 2.0f; for (var y = 0; y < gridlet.YLength; y++) { for (var x = 0; x < gridlet.XLength; x++) { var cellIndex = x + y * gridlet.XLength; var cell = gridlet.Cells[cellIndex]; var cellHeight = cell.Height; var vbOffset = cellIndex * 4; var uv = new Vector2(x / (float)(gridlet.XLength - 1), y / (float)(gridlet.YLength - 1)); vertices[vbOffset + 0] = new VertexPositionNormalTexture(new Vector3(x + xOffset, y + yOffset, cellHeight), Vector3.UnitZ, uv); vertices[vbOffset + 1] = new VertexPositionNormalTexture(new Vector3(x + 1 + xOffset, y + yOffset, cellHeight), Vector3.UnitZ, uv); vertices[vbOffset + 2] = new VertexPositionNormalTexture(new Vector3(x + 1 + xOffset, y + 1 + yOffset, cellHeight), Vector3.UnitZ, uv); vertices[vbOffset + 3] = new VertexPositionNormalTexture(new Vector3(x + xOffset, y + 1 + yOffset, cellHeight), Vector3.UnitZ, uv); var ibOffset = ibOffsetBase + cellIndex * 6; indices[ibOffset + 0] = vbOffset; indices[ibOffset + 1] = vbOffset + 3; indices[ibOffset + 2] = vbOffset + 1; indices[ibOffset + 3] = vbOffset + 1; indices[ibOffset + 4] = vbOffset + 3; indices[ibOffset + 5] = vbOffset + 2; } } ibOffsetBase = gridlet.XLength * gridlet.YLength * 6; for (var y = 0; y < gridlet.YLength - 1; y++) { for (var x = 0; x < gridlet.XLength - 1; x++) { var cellIndex = x + y * gridlet.XLength; var cell = gridlet.Cells[cellIndex]; var cellHeight = cell.Height; var vbOffset = cellIndex * 4; var rightVbOffset = vbOffset + 4; var downVbOffset = vbOffset + gridlet.XLength * 4; var ibOffset = ibOffsetBase + (x + y * (gridlet.XLength - 1)) * 12; indices[ibOffset + 0] = vbOffset + 1; indices[ibOffset + 1] = vbOffset + 2; indices[ibOffset + 2] = rightVbOffset; indices[ibOffset + 3] = rightVbOffset; indices[ibOffset + 4] = vbOffset + 2; indices[ibOffset + 5] = rightVbOffset + 3; indices[ibOffset + 6] = vbOffset + 2; indices[ibOffset + 7] = vbOffset + 3; indices[ibOffset + 8] = downVbOffset; indices[ibOffset + 9] = downVbOffset; indices[ibOffset + 10] = downVbOffset + 1; indices[ibOffset + 11] = vbOffset + 2; } } vertexBuffer = Buffer.Vertex.New(graphicsDevice, vertices); vertexInputLayout = VertexInputLayout.FromBuffer(0, vertexBuffer); indexBuffer = Buffer.Index.New(graphicsDevice, indices); }
static VertexPositionNormalTexture[] CalculateSphereVertices(float radius, float height, byte segments, byte rings) { VertexPositionNormalTexture[] data = new VertexPositionNormalTexture[segments * rings]; int i = 0; for (double y = 0; y < rings; y++) { double phi = (y / (rings - 1)) * Math.PI; for (double x = 0; x < segments; x++) { double theta = (x / (segments - 1)) * 2 * Math.PI; Vector3 v = new Vector3( (float)(radius * Math.Sin(phi) * Math.Cos(theta)), (float)(height * Math.Cos(phi)), (float)(radius * Math.Sin(phi) * Math.Sin(theta))); Vector3 n = Vector3.Normalize(v); Vector2 uv = new Vector2( (float)(x / (segments - 1)), (float)(y / (rings - 1))); // Using data[i++] causes i to be incremented multiple times in Mono 2.2 (bug #479506). data[i] = new VertexPositionNormalTexture(v, n, uv); i++; } } return data; }
/// <summary> /// Fills the texture type buffer (VertexPositionTexture) /// </summary> /// <param name="points">The points.</param> /// <param name="destinationSize">Size of the destination.</param> /// <param name="sourceRect">The source rect.</param> /// <param name="primitiveType">Type of the primitive.</param> public override void FillTexture(List<PointF> points, Size destinationSize, Rect sourceRect, GeometryPrimitiveType primitiveType) { SetPrimitiveCount(primitiveType, points.Count); VertexPositionNormalTexture[] vertex = new VertexPositionNormalTexture[points.Count]; for (int i = 0; i < points.Count; i++) { Vector2 uv = new Vector2(sourceRect.X + (points[i].X / destinationSize.Width) * sourceRect.Width, sourceRect.Y + (points[i].Y / destinationSize.Height) * sourceRect.Height); vertex[i] = new VertexPositionNormalTexture(new Vector3(points[i].X, points[i].Y, 0), new Vector3(0,0,1), uv); } VertexBuffer = VertexBuffer.Vertex.New(XenkoRenderer.GraphicsDevice, vertex); VertexBuffer.Reload = (graphicsResource) => ((VertexBuffer)graphicsResource).Recreate(vertex); VertexBufferBinding = new VertexBufferBinding(VertexBuffer, VertexPositionNormalTexture.Layout, vertex.Length, VertexPositionNormalTexture.Size); InputElementDescriptions = VertexBufferBinding.Declaration.CreateInputElements(); }