//Generates a mesh from required parameters, as well as specifying a parent bone to be used, used to simplify and clean up code. public static ModelMesh makeMeshFromPolygonList(List <Polygon> polys, GraphicsDevice graphics, ModelBone parentBone) { List <ModelMeshPart> parts = new List <ModelMeshPart>(); ModelBone bone = new ModelBone(); bone.Transform = Matrix.CreateTranslation(0, 0, 0); bone.ModelTransform = parentBone.ModelTransform; List <Vector3> points = new List <Vector3>(); foreach (Polygon p in polys) { ModelMeshPart part = makePartFromPolygon(p, graphics); parts.Add(part); foreach (Vector3 point in p.points) { points.Add(point); } } ModelMesh mesh = new ModelMesh(graphics, parts); bone.AddMesh(mesh); parentBone.AddChild(bone); bone.Parent = parentBone; mesh.ParentBone = bone; mesh.BoundingSphere = BoundingSphere.CreateFromPoints(points); return(mesh); }
//Generates a mesh from required parameters, used to simplify and clean up code. public static ModelMesh makeMeshFromPolygonList(List <Polygon> polys, GraphicsDevice graphics) { List <ModelMeshPart> parts = new List <ModelMeshPart>(); ModelBone bone = new ModelBone(); bone.Transform = Matrix.CreateTranslation(0, 0, 0); bone.ModelTransform = Matrix.CreateTranslation(0, 0, 0); Vector3 center = new Vector3(float.MaxValue, 0, 0); int pointCount = 0; foreach (Polygon p in polys) { ModelMeshPart part = makePartFromPolygon(p, graphics); parts.Add(part); foreach (Vector3 point in p.points) { pointCount++; if (center.X == float.MaxValue) { center = point; } else { center += point; } } } center /= pointCount; float radius = 0; foreach (Polygon p in polys) { foreach (Vector3 point in p.points) { radius = Vector3.Distance(point, center) > radius?Vector3.Distance(point, center) : radius; } } ModelMesh mesh = new ModelMesh(graphics, parts); bone.AddMesh(mesh); mesh.ParentBone = bone; mesh.BoundingSphere = new BoundingSphere(center, radius); return(mesh); }
public void Load() { CHeightmap heightmap = null; // for each heightmap component, create Model instance to enable Draw calls when rendering foreach (var renderable in Game1.Inst.Scene.GetComponents <C3DRenderable>()) { if (renderable.Value.GetType() != typeof(CHeightmap)) { continue; } heightmap = (CHeightmap)renderable.Value; int key = renderable.Key; /* use each color channel for different data, e.g. * R for height, * G for texture/material/terrain type, * B for fixed spawned models/entities (houses, trees etc.), * A for additional data */ List <ModelMesh> meshes = new List <ModelMesh>(); var bones = new List <ModelBone>(); var indices = new Dictionary <int, int[]>(); var vertices = new Dictionary <int, VertexPositionNormalColor[]>(); CreateIndicesChunk(heightmap, ref indices, 0); CalculateHeightData(heightmap, key); CreateVerticesChunks(heightmap, ref vertices, 0, 0); //basicEffect.Texture = heightmap.Image; basicEffect.DiffuseColor = new Vector3(1, 1, 1); basicEffect.SpecularPower = 100; basicEffect.SpecularColor = new Vector3(0.25f); basicEffect.EnableDefaultLighting(); basicEffect.LightingEnabled = true; basicEffect.AmbientLightColor = Game1.Inst.Scene.LightConfig.AmbientColor; basicEffect.DirectionalLight0.SpecularColor = Game1.Inst.Scene.LightConfig.SpecularColor; basicEffect.DirectionalLight0.Direction = Game1.Inst.Scene.LightConfig.Direction; basicEffect.DirectionalLight0.DiffuseColor = Game1.Inst.Scene.LightConfig.DiffuseColor; basicEffect.DirectionalLight0.Enabled = true; basicEffect.PreferPerPixelLighting = true; for (int j = 0; j < vertices.Values.Count; j++) { var vert = vertices[j]; var ind = indices[j]; CalculateNormals(ref vert, ref ind); /* * for(int i = 0; i < vertices[j].Length; i++) * vertices[j][i].Color = Color.ForestGreen; */ vertices[j] = vert; indices[j] = ind; var modelpart = CreateModelPart(vert, ind); List <ModelMeshPart> meshParts = new List <ModelMeshPart>(); meshParts.Add(modelpart); ModelMesh modelMesh = new ModelMesh(mGraphicsDevice, meshParts); modelMesh.BoundingSphere = new BoundingSphere(); ModelBone modelBone = new ModelBone(); modelBone.AddMesh(modelMesh); modelBone.Transform = Matrix.CreateTranslation(new Vector3(0, 0, 0)); // changing object world (frame) / origo modelMesh.ParentBone = modelBone; bones.Add(modelBone); meshes.Add(modelMesh); modelMesh.BoundingSphere = BoundingSphere.CreateFromBoundingBox(GenericUtil.BuildBoundingBoxForVertex(vert, Matrix.Identity)); modelpart.Effect = basicEffect; } ModelMeshPart ground = buildGround(heightmap, 20); List <ModelMeshPart> groundMeshParts = new List <ModelMeshPart>(); groundMeshParts.Add(ground); ModelMesh groundMesh = new ModelMesh(mGraphicsDevice, groundMeshParts); groundMesh.BoundingSphere = new BoundingSphere(); ModelBone groundBone = new ModelBone(); groundBone.AddMesh(groundMesh); groundBone.Transform = Matrix.CreateTranslation(new Vector3(0, 0, 0)); groundMesh.ParentBone = groundBone; groundMesh.Name = "FrontFace"; bones.Add(groundBone); meshes.Add(groundMesh); ground.Effect = basicEffect; heightmap.model = new Model(mGraphicsDevice, bones, meshes); heightmap.model.Tag = "Map"; } }
public void Load() { Model model = null; foreach (var renderable in Game1.Inst.Scene.GetComponents <C3DRenderable>()) { if (renderable.Value.GetType() != typeof(CHeightmap)) { continue; } CHeightmap heightmap = (CHeightmap)renderable.Value; // heightmap.HeightData // Create vertices Random rnd = new Random(1990); var terrainHeight = 1081; var terrainWidth = 1081; // int counter = 0; indices = new int[(terrainWidth - 1) * (terrainHeight - 1) * 6]; vertices = new VertexPositionNormalColor[terrainWidth * terrainHeight]; vibirations = new int[terrainWidth * terrainHeight]; // Create vertices for (int x = 0; x < terrainWidth; x++) { for (int y = 0; y < terrainHeight; y++) { vertices[x + y * terrainWidth].Position = new Vector3(x, heightmap.LowestPoint + 10, y); var color = Color.Blue; color.A = 100; vertices[x + y * terrainWidth].Color = color; // Randomly set the direction of the vertex up or down vibirations[x + y * terrainWidth] = rnd.Next(0, 100) > 50 ? -1 : 1; } } for (int y = 0; y < terrainHeight - 1; y++) { for (int x = 0; x < terrainWidth - 1; x++) { int topLeft = x + y * terrainWidth; int topRight = (x + 1) + y * terrainWidth; int lowerLeft = x + (y + 1) * terrainWidth; int lowerRight = (x + 1) + (y + 1) * terrainWidth; indices[counter++] = (int)topLeft; indices[counter++] = (int)lowerRight; indices[counter++] = (int)lowerLeft; indices[counter++] = (int)topLeft; indices[counter++] = (int)topRight; indices[counter++] = (int)lowerRight; } } // Calculate normals for (int i = 0; i < vertices.Length; i++) { vertices[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 = vertices[index1].Position - vertices[index3].Position; Vector3 side2 = vertices[index1].Position - vertices[index2].Position; Vector3 normal = Vector3.Cross(side1, side2); vertices[index1].Normal += normal; vertices[index2].Normal += normal; vertices[index3].Normal += normal; } var vertexBuffer = new VertexBuffer(mGraphicsDevice, VertexPositionNormalColor.VertexDeclaration, vertices.Length, BufferUsage.None); vertexBuffer.SetData(vertices); var indexBuffer = new IndexBuffer(mGraphicsDevice, typeof(int), indices.Length, BufferUsage.None); indexBuffer.SetData(indices); var bones = new List <ModelBone>(); var meshes = new List <ModelMesh>(); List <ModelMeshPart> parts = new List <ModelMeshPart>(); ModelMeshPart meshPart = new ModelMeshPart(); meshPart.VertexBuffer = vertexBuffer; meshPart.IndexBuffer = indexBuffer; meshPart.NumVertices = indices.Length; meshPart.PrimitiveCount = indices.Length / 3; parts.Add(meshPart); ModelMesh mesh = new ModelMesh(mGraphicsDevice, parts); meshPart.Effect = bEffect; mesh.Name = "water"; ModelBone bone = new ModelBone(); bone.Name = "Water"; bone.AddMesh(mesh); bone.Transform = Matrix.Identity; mesh.ParentBone = bone; bones.Add(bone); meshes.Add(mesh); model = new Model(Game1.Inst.GraphicsDevice, bones, meshes); } int id = Game1.Inst.Scene.AddEntity(); Game1.Inst.Scene.AddComponent(id, new CTransform() { Position = new Vector3(-590, -900, -590) * 0.01f, Orientation = Quaternion.CreateFromRotationMatrix(Matrix.Identity), Scale = new Vector3(0.01f) }); CModel = new CImportedModel() { model = model }; Game1.Inst.Scene.AddComponent <C3DRenderable>(id, CModel); }
public void Load() { // for each heightmap component, create Model instance to enable Draw calls when rendering foreach (var renderable in Game1.Inst.Scene.GetComponents <C3DRenderable>()) { if (renderable.Value.GetType() != typeof(CHeightmap)) { continue; } CHeightmap heightmap = (CHeightmap)renderable.Value; /* use each color channel for different data, e.g. * R for height, * G for texture/material/terrain type, * B for fixed spawned models/entities (houses, trees etc.), * A for additional data */ List <ModelMesh> meshes = new List <ModelMesh>(); var bones = new List <ModelBone>(); var indices = new Dictionary <int, int[]>(); var vertices = new Dictionary <int, VertexPositionNormalColor[]>(); CreateIndicesChunk(heightmap, ref indices, 0); CalculateHeightData(heightmap); CreateVerticesChunks(heightmap, ref vertices, 0, 0); for (int j = 0; j < vertices.Values.Count; j++) { var vert = vertices[j]; var ind = indices[j]; CalculateNormals(ref vert, ref ind); vertices[j] = vert; indices[j] = ind; var modelpart = CreateModelPart(vert, ind); List <ModelMeshPart> meshParts = new List <ModelMeshPart>(); meshParts.Add(modelpart); ModelMesh modelMesh = new ModelMesh(mGraphicsDevice, meshParts); modelMesh.BoundingSphere = new BoundingSphere(); ModelBone modelBone = new ModelBone(); modelBone.AddMesh(modelMesh); modelBone.Transform = Matrix.CreateTranslation(new Vector3(0, 0, 0)); // changing object world (frame) / origo modelMesh.ParentBone = modelBone; bones.Add(modelBone); meshes.Add(modelMesh); modelMesh.BoundingSphere = BoundingSphere.CreateFromBoundingBox(GenericUtil.BuildBoundingBoxForVertex(vert, Matrix.Identity)); modelpart.Effect = basicEffect; } ModelMeshPart ground = buildGround(heightmap, 20); List <ModelMeshPart> groundMeshParts = new List <ModelMeshPart>(); groundMeshParts.Add(ground); ModelMesh groundMesh = new ModelMesh(mGraphicsDevice, groundMeshParts); groundMesh.BoundingSphere = new BoundingSphere(); ModelBone groundBone = new ModelBone(); groundBone.AddMesh(groundMesh); groundBone.Transform = Matrix.CreateTranslation(new Vector3(0, 0, 0)); groundMesh.ParentBone = groundBone; groundMesh.Name = "FrontFace"; bones.Add(groundBone); meshes.Add(groundMesh); ground.Effect = basicEffect; heightmap.model = new Model(mGraphicsDevice, bones, meshes); heightmap.model.Tag = "Map"; } }
public static void CreateSplatter(float x, float z, Heightmap heightmap) { var graphicsDevice = Game1.Inst.GraphicsDevice; var scene = Game1.Inst.Scene; // vertical offset to avoid flickering var yOffset = 0.1f; var y = heightmap.HeightAt(x, z); var A = new Vector3(-0.5f, 0.0f, -0.5f); var B = new Vector3(0.5f, 0.0f, -0.5f); var C = new Vector3(0.5f, 0.0f, 0.5f); var D = new Vector3(-0.5f, 0.0f, 0.5f); A.Y = heightmap.HeightAt(x + A.X, z + A.Z) - y; B.Y = heightmap.HeightAt(x + B.X, z + B.Z) - y; C.Y = heightmap.HeightAt(x + C.X, z + C.Z) - y; D.Y = heightmap.HeightAt(x + D.X, z + D.Z) - y; var N = -Vector3.Cross(A - B, A - D); N.Normalize(); var vertices = new VertexPositionNormalTexture[4]; vertices[0] = new VertexPositionNormalTexture(A, N, new Vector2(0, 0)); vertices[1] = new VertexPositionNormalTexture(B, N, new Vector2(1, 0)); vertices[2] = new VertexPositionNormalTexture(C, N, new Vector2(1, 1)); vertices[3] = new VertexPositionNormalTexture(D, N, new Vector2(0, 1)); var indices = new short[6]; indices[0] = 0; indices[1] = 1; indices[2] = 2; indices[3] = 0; indices[4] = 2; indices[5] = 3; var vertexBuffer = new VertexBuffer(graphicsDevice, VertexPositionNormalTexture.VertexDeclaration, vertices.Length, BufferUsage.None); vertexBuffer.SetData(vertices); var indexBuffer = new IndexBuffer(graphicsDevice, typeof(short), indices.Length, BufferUsage.None); indexBuffer.SetData(indices); var bEffect = new BasicEffect(graphicsDevice); bEffect.TextureEnabled = true; bEffect.Texture = Game1.Inst.Content.Load <Texture2D>("Textures/splatter"); var meshes = new List <ModelMesh>(); var parts = new List <ModelMeshPart>(); var bones = new List <ModelBone>(); parts.Add(new ModelMeshPart { VertexBuffer = vertexBuffer, NumVertices = vertices.Length, IndexBuffer = indexBuffer, PrimitiveCount = indices.Length / 3 }); var mesh = new ModelMesh(graphicsDevice, parts); parts[0].Effect = bEffect; var bone = new ModelBone { Name = "Splatter", Transform = Matrix.Identity }; bone.AddMesh(mesh); mesh.ParentBone = bone; bones.Add(bone); meshes.Add(mesh); var model = new Model(graphicsDevice, bones, meshes); var id = scene.AddEntity(); scene.AddComponent <C3DRenderable>(id, new CImportedModel { model = model }); scene.AddComponent(id, new CTransform { Position = new Vector3(x, y + yOffset, z), Scale = new Vector3((float)rnd.NextDouble() * 0.5f + 1.5f) }); }
public static void Create(float WaterHeight = -33, float TerrainWidth = 300f, float TerrainDepth = 300f) { byte WaterOpacity = 100; int Resolution = 100; // vertices per direction float Frequency = 1.5f; float Amplitude = 0.2f; GraphicsDevice mGraphicsDevice = Game1.Inst.GraphicsDevice; int[] indices = null; VertexPositionNormalTexture[] vertices; Effect bEffect = Game1.Inst.Content.Load <Effect>("Effects/Water"); bEffect.Parameters["Frequency"].SetValue(Frequency); bEffect.Parameters["Amplitude"].SetValue(Amplitude); var lightConfig = Game1.Inst.Scene.LightConfig; bEffect.Parameters["FogStart"].SetValue(lightConfig.FogStart); bEffect.Parameters["FogEnd"].SetValue(lightConfig.FogEnd); bEffect.Parameters["FogColor"].SetValue(lightConfig.ClearColor); int counter = 0; indices = new int[(Resolution - 1) * (Resolution - 1) * 6]; vertices = new VertexPositionNormalTexture[Resolution * Resolution]; // Create vertices for (int x = 0; x < Resolution; x++) { for (int y = 0; y < Resolution; y++) { var vx = TerrainWidth * (float)((float)x / Resolution - 0.5f); var vy = TerrainDepth * (float)((float)y / Resolution - 0.5f); var txs = 1.0f; var u = txs * (float)x / Resolution; var v = txs * (float)y / Resolution; vertices[x + y * Resolution].Position = new Vector3(vx, WaterHeight, vy); var color = Color.Blue; color.A = WaterOpacity; vertices[x + y * Resolution].TextureCoordinate = new Vector2(u, v); } } for (int y = 0; y < Resolution - 1; y++) { for (int x = 0; x < Resolution - 1; x++) { int topLeft = x + y * Resolution; int topRight = (x + 1) + y * Resolution; int lowerLeft = x + (y + 1) * Resolution; int lowerRight = (x + 1) + (y + 1) * Resolution; indices[counter++] = (int)topLeft; indices[counter++] = (int)lowerRight; indices[counter++] = (int)lowerLeft; indices[counter++] = (int)topLeft; indices[counter++] = (int)topRight; indices[counter++] = (int)lowerRight; } } // Calculate normals for (int i = 0; i < vertices.Length; i++) { vertices[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 = vertices[index1].Position - vertices[index3].Position; Vector3 side2 = vertices[index1].Position - vertices[index2].Position; Vector3 normal = Vector3.Cross(side1, side2); vertices[index1].Normal += normal; vertices[index2].Normal += normal; vertices[index3].Normal += normal; } var vertexBuffer = new VertexBuffer(mGraphicsDevice, VertexPositionNormalTexture.VertexDeclaration, vertices.Length, BufferUsage.None); vertexBuffer.SetData(vertices); var indexBuffer = new IndexBuffer(mGraphicsDevice, typeof(int), indices.Length, BufferUsage.None); indexBuffer.SetData(indices); var bones = new List <ModelBone>(); var meshes = new List <ModelMesh>(); List <ModelMeshPart> parts = new List <ModelMeshPart>(); ModelMeshPart meshPart = new ModelMeshPart(); meshPart.VertexBuffer = vertexBuffer; meshPart.IndexBuffer = indexBuffer; meshPart.NumVertices = indices.Length; meshPart.PrimitiveCount = indices.Length / 3; parts.Add(meshPart); ModelMesh mesh = new ModelMesh(mGraphicsDevice, parts); meshPart.Effect = bEffect; mesh.Name = "water"; mesh.BoundingSphere = BoundingSphere.CreateFromBoundingBox(new BoundingBox(new Vector3(0, WaterHeight, 0), new Vector3(TerrainWidth, WaterHeight, TerrainDepth))); ModelBone bone = new ModelBone(); bone.Name = "water"; bone.AddMesh(mesh); bone.Transform = Matrix.Identity; mesh.ParentBone = bone; bones.Add(bone); meshes.Add(mesh); var model = new Model(Game1.Inst.GraphicsDevice, bones, meshes); int id = Game1.Inst.Scene.AddEntity(); Game1.Inst.Scene.AddComponent(id, new CTransform { Position = Vector3.Zero, Rotation = Matrix.Identity, Scale = new Vector3(1f) }); var CModel = new CWater() { model = model, materials = new Dictionary <int, MaterialShader> { { 0, new MaterialShader(bEffect) } } }; Game1.Inst.Scene.AddComponent(id, CModel); }
/// <summary>Creates the MonoGame/XNA renderable model.</summary> /// <param name="indices">The triangle indices.</param> /// <param name="verts">The model vertices.</param> private void CreateModel(int[] indices, VertexPositionNormalColor[] verts, Func <float, float, float, Color> calcColor) { //-------------------- // Compute normals. //-------------------- for (var i = 0; i < indices.Length - 2; i += 3) { var i0 = indices[i]; var i1 = indices[i + 1]; var i2 = indices[i + 2]; Vector3 a = verts[i0].Position - verts[i2].Position; Vector3 b = verts[i0].Position - verts[i1].Position; Vector3 n = Vector3.Cross(a, b); verts[i0].Normal += n; verts[i1].Normal += n; verts[i2].Normal += n; if (true || !mSmooth) { var c = new Color((verts[i0].Color.R + verts[i1].Color.R + verts[i2].Color.R) / 3, (verts[i0].Color.G + verts[i1].Color.G + verts[i2].Color.G) / 3, (verts[i0].Color.B + verts[i1].Color.B + verts[i2].Color.B) / 3); verts[i0].Color = verts[i1].Color = verts[i2].Color = c; } } for (var i = 0; i < verts.Length; i++) { verts[i].Normal.Normalize(); } //-------------------- // Setup model. //-------------------- // TODO: The code below is retarded. Blame XNA/MonoGame. :-( var device = Game1.Inst.GraphicsDevice; var ibo = new IndexBuffer(device, typeof(int), indices.Length, BufferUsage.None); ibo.SetData(indices); var vbo = new VertexBuffer(device, VertexPositionNormalColor.VertexDeclaration, verts.Length, BufferUsage.None); vbo.SetData(verts); var meshes = new List <ModelMesh>(); var parts = new List <ModelMeshPart>(); var bones = new List <ModelBone>(); parts.Add(new ModelMeshPart { VertexBuffer = vbo, NumVertices = verts.Length, IndexBuffer = ibo, PrimitiveCount = indices.Length / 3, }); var mesh = new ModelMesh(device, parts); parts[0].Effect = new BasicEffect(device); var bone = new ModelBone { Name = "Heightmap", Transform = Matrix.Identity }; bone.AddMesh(mesh); mesh.ParentBone = bone; bones.Add(bone); meshes.Add(mesh); Model = new Model(device, bones, meshes); Model.Tag = "Heightmap"; }