private void GenerateSurface() { surfaceTool.Begin(Mesh.PrimitiveType.Triangles); for (int x = 0; x < SIZE.x; x++) { for (int y = 0; y < SIZE.y; y++) { for (int z = 0; z < SIZE.z; z++) { byte blockType = blocks[x, y, z]; if (blockType == 0) { continue; } Block block = Game.GetBlock(blockType); IntVector3 localIndex = new IntVector3(x, y, z); //Index in world space IntVector3 index = localIndex + new IntVector3(chunkCoords.x * SIZE.x, 0, chunkCoords.y * SIZE.z); //Position in chunk Vector3 localBlockPosition = localIndex * Block.SIZE; if (terrain.GetBlock(index.x + 1, index.y, index.z) == AIR_ID) { block.AddPosXFace(ref surfaceTool, localBlockPosition, blockType); } if (terrain.GetBlock(index.x - 1, index.y, index.z) == AIR_ID) { block.AddNegXFace(ref surfaceTool, localBlockPosition, blockType); } if (terrain.GetBlock(index.x, index.y + 1, index.z) == AIR_ID) { block.AddPosYFace(ref surfaceTool, localBlockPosition, blockType); } if (index.y != 0 && terrain.GetBlock(index.x, index.y - 1, index.z) == AIR_ID) //Don't draw bottom face { block.AddNegYFace(ref surfaceTool, localBlockPosition, blockType); } if (terrain.GetBlock(index.x, index.y, index.z + 1) == AIR_ID) { block.AddPosZFace(ref surfaceTool, localBlockPosition, blockType); } if (terrain.GetBlock(index.x, index.y, index.z - 1) == AIR_ID) { block.AddNegZFace(ref surfaceTool, localBlockPosition, blockType); } } } } surfaceTool.GenerateNormals(); surfaceTool.SetMaterial(material); surfaceTool.Index(); }
public Mesh CreateMesh() { SurfaceTool.Begin(Mesh.PrimitiveType.Triangles); SurfaceTool.SetMaterial(DefaultMaterial); foreach (var voxel in Voxels.Keys) { CreateVoxel(Voxels[voxel], voxel); } SurfaceTool.Index(); return(SurfaceTool.Commit()); }
public void BuildVoxelMesh() { Builder.Begin(Mesh.PrimitiveType.Triangles); // GD.Print("Builder has begun!"); Builder.SetMaterial(voxelMaterial); foreach (VoxelPos pos in Voxels.Keys) { var voxel = GetVoxel(pos, false); if (voxel.HasFront()) { BuildFace(pos.ToVector3(), Vector3.Right, Vector3.Up, UVFromName(voxel.frontTexture), Vector3.Forward); } if (voxel.HasBack()) { BuildFace(pos.Backwards().ToVector3(), Vector3.Up, Vector3.Right, UVFromName(voxel.backTexture), Vector3.Back); } if (voxel.HasLeft()) { BuildFace(pos.ToVector3(), Vector3.Up, Vector3.Back, UVFromName(voxel.leftTexture), Vector3.Left); } if (voxel.HasRight()) { BuildFace(pos.Right().ToVector3(), Vector3.Back, Vector3.Up, UVFromName(voxel.rightTexture), Vector3.Right); } if (voxel.HasTop()) { BuildFace(pos.Up().ToVector3(), Vector3.Right, Vector3.Back, UVFromName(voxel.topTexture), Vector3.Up); } if (voxel.HasBottom()) { BuildFace(pos.ToVector3(), Vector3.Back, Vector3.Right, UVFromName(voxel.bottomTexture), Vector3.Down); } } Builder.Index(); var voxelMesh = GetNode <MeshInstance>("VoxelMesh"); voxelMesh.Mesh = Builder.Commit(); Builder.Clear(); /* * foreach (KeyValuePair<VoxelPos, Voxel> pair in Voxels) * { * GD.Print($"{pair.Key}: {pair.Value}"); * } */ }
//Creates a surface tool for mesh creation public static SurfaceTool CreateSurfaceTool(SpatialMaterial material = null) { var surfTool = new SurfaceTool(); surfTool.Begin(Mesh.PrimitiveType.Triangles); if (material == null) { material = new SpatialMaterial(); //material.SetEmission(new Color(1.0f, 0.0f, 0.0f)); //material.SetEmissionEnergy(0.5f); material.SetAlbedo(new Color(0.5f, 0.0f, 0.0f)); //material.SetMetallic(0.5f); material.SetCullMode(SpatialMaterial.CullMode.Back); } surfTool.SetMaterial(material); return(surfTool); }
public void generateMeshAndColors(float[,] dataTerrain) { //init tool SurfaceTool st = new SurfaceTool(); st.Begin(Mesh.PrimitiveType.Triangles); st.SetMaterial(mat); //get HeightsQuats and create triangles int maxI = dataTerrain.GetLength(0); int maxJ = dataTerrain.GetLength(1); int quadCount = 0; //1º rows, 2º columns for (int i = 0; i < maxI - 1; i++) { for (int j = 0; j < maxJ - 1; j++) { Quat q = new Quat();//heights to Quat q.x = dataTerrain[i, j]; q.y = dataTerrain[i, j + 1]; q.z = dataTerrain[i + 1, j]; q.w = dataTerrain[i + 1, j + 1]; //to mesh Vector3 offset = new Vector3(j, 0, i); createQuad(st, offset, q); /*//debug algoritm * GD.Print(string.Format("•quad{0}:({1},{2}): points: \n{3} {4} {5} {6} {7} {8}\n{9} {10} {11} {12} {13} {14}", * quadCount,i,j, * offset.x, q.x, offset.z - 1, offset.x + 1, q.y, offset.z-1, * offset.x, q.z, offset.z, offset.x + 1, q.w, offset.z)); */ quadCount++; } } //finally st.GenerateNormals(); st.Commit(tmpMesh); this.SetMesh(tmpMesh); }
// Generates sphere with radius 1 public void GenerateSphere(int iterations) { float radius = 10f; System.Diagnostics.Debug.WriteLine("Generating sphere!"); Stopwatch totalTimer = new Stopwatch(); totalTimer.Start(); SurfaceTool surfaceTool = new SurfaceTool(); this.planetMesh = new ArrayMesh(); material.VertexColorUseAsAlbedo = true; surfaceTool.SetMaterial(material); surfaceTool.Begin(PrimitiveType.Triangles); // GENERATE SPHERE: Stopwatch planetGeneratorTimer = new Stopwatch(); planetGeneratorTimer.Start(); // 9 gives ~30s generate time, which is acceptable this.currentStatus = "Generating base topology (this step can take long!)"; PlanetTopologyData[] planetData = pg.GenerateBaseTopology(iterations, radius); planetGeneratorTimer.Stop(); TimeSpan ts = planetGeneratorTimer.Elapsed; System.Diagnostics.Debug.WriteLine("Sphere generated. Number of faces: " + (planetData[0].faces.Count * 20) + "; time needed: " + ts.Minutes + "m " + ts.Seconds + "." + ts.Milliseconds); // todo: create biomes // Add perlino Stopwatch perlinTimer = new Stopwatch(); perlinTimer.Start(); this.currentStatus = "Adding perlin noise ..."; Parallel.For(0, planetData.Length, new ParallelOptions { MaxDegreeOfParallelism = System.Environment.ProcessorCount }, i => { PlanetTopologyData data = planetData[i]; data.vertices = pg.AddPerlinDisplacement(data.vertices, radius, 16, 0.42f); // float maxDispalcement = 0; // float maxNegDisplacement = 0; // foreach (PlanetVertex pv in data.vertices) { // if (pv.h > maxDispalcement) { // maxDispalcement = pv.h; // } // if (pv.h < maxNegDisplacement) { // maxNegDisplacement = pv.h; // } // } // Debug.WriteLine("Max displacement for this face (from-to) " + maxNegDisplacement +" -> " + maxDispalcement); }); perlinTimer.Stop(); ts = perlinTimer.Elapsed; System.Diagnostics.Debug.WriteLine("Perlin applied. Time needed: " + ts.Minutes + "m " + ts.Seconds + "." + ts.Milliseconds); Stopwatch surfaceToolTimer = new Stopwatch(); surfaceToolTimer.Start(); this.currentStatus = "Building planet mesh ..."; // // Possible future for multithreading ahead. Might happen some day. // // SurfaceTool[] surfaceTool = new SurfaceTool[planetData.Length]; // this.planetMeshes = new ArrayMesh[planetData.Length]; // material.VertexColorUseAsAlbedo = true; // Parallel.For(0, planetData.Length, new ParallelOptions {MaxDegreeOfParallelism = System.Environment.ProcessorCount}, i => { // surfaceTool[i] = new SurfaceTool(); // this.planetMeshes[i] = new ArrayMesh(); // surfaceTool[i].SetMaterial(material); // surfaceTool[i].Begin(PrimitiveType.Triangles); // for (int j = 0; j < planetData[i].faces.Count; j++) { // planetData[i].faces[j].AddToSurfaceTool(surfaceTool[i]); // } // surfaceTool[i].GenerateNormals(); // surfaceTool[i].Commit(this.planetMeshes[i]); // }); int faceCount; for (int i = 0; i < planetData.Length; i++) { faceCount = planetData[i].faces.Count; for (int j = 0; j < faceCount; j++) { planetData[i].faces[j].AddToSurfaceTool(surfaceTool); } } // foreach (PlanetTopologyData data in planetData) { // foreach (PlanetCell c in data.faces) { // c.AddToSurfaceTool(surfaceTool); // } // } surfaceTool.GenerateNormals(); surfaceTool.Commit(this.planetMesh); surfaceToolTimer.Stop(); ts = surfaceToolTimer.Elapsed; System.Diagnostics.Debug.WriteLine("SurfaceTool generated our mesh. Time needed: " + ts.Minutes + "m " + ts.Seconds + "." + ts.Milliseconds); totalTimer.Stop(); ts = totalTimer.Elapsed; System.Diagnostics.Debug.WriteLine("————————————————— total time needed: " + ts.Minutes + "m " + ts.Seconds + "." + ts.Milliseconds + "—————————————————"); this.Mesh = planetMesh; this.currentStatus = ""; }
public MeshInstance CreateChunkMesh(Chunk chunk) { MeshInstance instance = new MeshInstance(); SurfaceTool surfacetool = new SurfaceTool(); surfacetool.Begin(Mesh.PrimitiveType.Points); surfacetool.SetMaterial(chunkMaterial); int count = 0; for (int i = 0; i < Constants.CHUNK_SIZE3D / chunk.Materials; i++) { Run run = chunk.Voxels[i]; int objectID = run.value; TerraObject terraObject = registry.SelectByID((int)objectID); var x = i % CHUNK_SIZE; var y = (i / CHUNK_SIZE) % CHUNK_SIZE; var z = i / (CHUNK_SIZE * CHUNK_SIZE); if (chunk.Voxels[i].value != 0) { int face = 0b000000; //Left if (x == 0 || chunk.Voxels[i - 1].value != objectID) { face = 0b000001; } //Right else if (x == 63 || chunk.Voxels[i + 1].value != objectID) { face = 0b000010; } //Top else if (y == 63 || chunk.Voxels[i + 64].value != objectID) { face = 0b000100; } //Bottom else if (y == 0 || chunk.Voxels[i - 64].value != objectID) { face = 0b001000; } //Back else if (z == 63 || chunk.Voxels[i + 4096].value != objectID) { face = 0b010000; } //Front else if (z == 0 || chunk.Voxels[i - 4096].value != objectID) { face = 0b100000; } if (face != 0b000000) { int counter = 0; Vector3 normalAvg = Vector3.Zero; for (int j = 0; j < 6; j++) { int bitFlagN = (face >> j) & 1; if (bitFlagN == 1) { normalAvg = normalAvg + Normals[j]; counter += 1; } } count += 1; surfacetool.AddColor(new Color(1f, 1f, 1f, 1f)); Vector3 voxPosition = new Vector3((x) * VOX_SIZE, (y) * VOX_SIZE, (z) * VOX_SIZE); voxPosition.x = voxPosition.x + (chunk.x * CHUNK_SIZE * VOX_SIZE); voxPosition.y = voxPosition.y + (chunk.y * CHUNK_SIZE * VOX_SIZE); voxPosition.z = voxPosition.z + (chunk.z * CHUNK_SIZE * VOX_SIZE); if (counter > 0) { normalAvg = normalAvg / counter; surfacetool.AddNormal(normalAvg); } surfacetool.AddVertex(voxPosition); } } } surfacetool.Index(); instance.Mesh = surfacetool.Commit(); surfacetool.Clear(); instance.MaterialOverride = chunkMaterial.Duplicate() as ShaderMaterial; // Console.WriteLine("Mesh AABB Pos: {0} , Size: {1}, End: {2}",bb.Position,bb.Size,bb.End); return(instance); }
private void Render(Chunk pChunk) { // If chunk is already loaded. if (LoadedChunks.ContainsKey(pChunk.Offset)) { return; } SurfaceTool = new SurfaceTool(); SurfaceTool.Begin(Mesh.PrimitiveType.Triangles); // Adding material Material mat = VoxMaterial.Duplicate() as Material; SurfaceTool.SetMaterial(mat); // Creating the mesh. Voxel by voxel for (int y = 0; y < Chunk.ChunkSize.y; y++) { for (int x = 0; x < Chunk.ChunkSize.x; x++) { for (int z = 0; z < Chunk.ChunkSize.z; z++) { if (!pChunk.Voxels[x, y, z].Active) { continue; } CreateVoxel(SurfaceTool, x, y, z, pChunk); } } } // Reduces vertex size SurfaceTool.Index(); // Creating instance MeshInstance chunk = new MeshInstance { Mesh = SurfaceTool.Commit(), Name = pChunk.Offset.ToString(), Translation = new Vector3(pChunk.Offset.x * Chunk.ChunkSize.x, 0, pChunk.Offset.y * Chunk.ChunkSize.z) }; // Creating collisions //chunk.CreateTrimeshCollision(); // Tagging the chunk chunk.AddToGroup("Chunk"); // Chunk is now loaded. Adding to the scene. LoadedChunks.TryAdd(pChunk.Offset, pChunk); this.CallDeferred("add_child", chunk); if (pChunk.VoxelSprite.Count < 64) { // Adding voxelsprite foreach (VoxelSprite voxSprite in pChunk.VoxelSprite) { var meshInstance = new MeshInstance(); meshInstance.SetDeferred("mesh", voxSprite.Mesh); // Adding next frame to avoid locking problems. chunk.CallDeferred("add_child", meshInstance); // Moving next frame because not in tree yet meshInstance.SetDeferred("translation", voxSprite.Position); // Applying wind shader. meshInstance.SetDeferred("material_override", GrassMaterial); // Scaling down because its a decoration meshInstance.Scale = meshInstance.Scale /= 8; } } // Fade in animation. //var t2 = new Tween(); //chunk.AddChild(t2); //t2.InterpolateProperty(mat, "albedo_color", new Color(1, 1, 1, 0f), new Color(1, 1, 1, 1f), 1f, Tween.TransitionType.Linear, Tween.EaseType.InOut); //t2.Start(); SurfaceTool.Clear(); }
public void CreateMesh(Tile tile, PackedScene sphereMeshScene, PackedScene greenSphereMeshScene, int numberOfTiles, float radius) { var surfTool = new SurfaceTool(); var mesh = new ArrayMesh(); var material = new SpatialMaterial(); material.SetEmission(new Color(1.0f, 0.0f, 0.0f)); material.SetAlbedo(new Color(1.0f, 0.0f, 0.0f)); surfTool.SetMaterial(material); surfTool.Begin(Mesh.PrimitiveType.LineLoop); decimal tileCenterX = 0; decimal tileCenterY = 0; decimal tileCenterZ = 0; decimal polygonRadius = 0; List <Point> points = tile.boundary; var lastPoint = points[points.Count - 1]; Vector3 lastPointVector = new Vector3((float)lastPoint.x, (float)lastPoint.y, (float)lastPoint.z); decimal polygonSideLength = 0; foreach (Point point in points) { surfTool.AddUv(new Vector2(0, 0)); surfTool.AddVertex(new Vector3((float)point.x, (float)point.y, (float)point.z)); tileCenterX += point.x / points.Count; tileCenterY += point.y / points.Count; tileCenterZ += point.z / points.Count; Vector3 currentVector = new Vector3((float)point.x, (float)point.y, (float)point.z); polygonSideLength += (decimal)currentVector.DistanceTo(lastPointVector); lastPointVector = currentVector; } polygonSideLength = polygonSideLength / points.Count; var tileCenterPoint = new Vector3((float)tileCenterX, (float)tileCenterY, (float)tileCenterZ); var firstPoint = new Vector3((float)points[0].x, (float)points[0].y, (float)points[0].z); foreach (Point point in points) { var vector = new Vector3((float)point.x, (float)point.y, (float)point.z); polygonRadius += (decimal)vector.DistanceTo(tileCenterPoint); } polygonRadius = polygonRadius / points.Count; var polygonRotation = firstPoint.AngleTo(tileCenterPoint); var sphereCenterPoint = new Vector3(0f, 0f, 0f); var sphereScale = radius / numberOfTiles; MeshInstance sphere = (MeshInstance)sphereMeshScene.Instance(); sphere.SetTranslation(tileCenterPoint); sphere.SetScale(new Vector3(sphereScale, sphereScale, sphereScale)); this.AddChild(sphere); MeshInstance sphere2 = (MeshInstance)greenSphereMeshScene.Instance(); sphere2.SetTranslation(firstPoint); sphere2.SetScale(new Vector3(sphereScale, sphereScale, sphereScale)); this.AddChild(sphere2); MeshInstance sphere3 = (MeshInstance)greenSphereMeshScene.Instance(); sphere3.SetTranslation((firstPoint - tileCenterPoint) / 2 + tileCenterPoint); sphere3.SetScale(new Vector3(sphereScale, sphereScale, sphereScale)); this.AddChild(sphere3); surfTool.GenerateNormals(); surfTool.Index(); surfTool.Commit(mesh); var meshInstance = new MeshInstance(); meshInstance.SetMesh(mesh); this.AddChild(meshInstance); }