public HeightPyramidSegmentShapeGroup CreateGroup(HeightPyramidLevelTemplate pyramidLevelTemplate, HeightPyramidLevel level, GameObject pyramidRootGo) { var parentGO = new GameObject("ETerrainParent " + level); var center = pyramidLevelTemplate.Center; parentGO.transform.localPosition = new Vector3(center.x, 0, center.y); var ringTemplateElementMesh = _meshGenerator.AddOrder(() => PlaneGenerator.CreateETerrainSegmentMesh(_perLevelConfiguration.RingObjectMeshVertexLength.X, _perLevelConfiguration.RingObjectMeshVertexLength.Y)) .Result; //todo var centerMesh = _meshGenerator.AddOrder(() => PlaneGenerator.CreateETerrainSegmentMesh(_perLevelConfiguration.CenterObjectMeshVertexLength.X, _perLevelConfiguration.CenterObjectMeshVertexLength.Y)) .Result; //todo var shapeMeshesToCombine = new List <CombineInstance>(); foreach (var shapeTemplate in pyramidLevelTemplate.ShapeTemplates) { Mesh thisSegmentMesh = null; if (shapeTemplate.RingIndex == 0) //center { thisSegmentMesh = centerMesh; } else { thisSegmentMesh = ringTemplateElementMesh; } var trs = CreateTrsMatrixForShape(shapeTemplate); shapeMeshesToCombine.Add(new CombineInstance() { transform = trs, mesh = thisSegmentMesh }); } var finalMesh = _meshGenerator.AddOrder(() => { var m = MeshGenerationUtils.CreateMeshAsSum(shapeMeshesToCombine); MeshGenerationUtils.RecalculateUvAsInPlane(m); return(m); }).Result; //TODO MeshGenerationUtils.SetYBoundsToInfinity(finalMesh); var mainObject = CreateShapeObject(finalMesh, "MainObject", center, pyramidLevelTemplate.FlatSize); mainObject.transform.SetParent(parentGO.transform); parentGO.transform.localScale = new Vector3(1, _commonConfiguration.YScale, 1); parentGO.transform.SetParent(pyramidRootGo.transform); return(new HeightPyramidSegmentShapeGroup() { CentralShape = mainObject, ParentGameObject = parentGO, }); }
public void Start() { _rootParent = new GameObject("EPropDummyObjectDisplayer"); _perScopeParents = new Dictionary <uint, GameObject>(); _dummyObjects = new Dictionary <EPropElevationId, GameObject>(); var newGo = GameObject.CreatePrimitive(PrimitiveType.Sphere); _dummyMesh = MeshGenerationUtils.CloneMesh(newGo.GetComponent <MeshFilter>().mesh); var bounds = _dummyMesh.bounds; bounds.Expand(1000); _dummyMesh.bounds = bounds; }
public HeightPyramidSegmentShapeGroup CreateGroup(HeightPyramidLevelTemplate pyramidLevelTemplate, HeightPyramidLevel level, GameObject pyramidRootGo) { var parentGO = new GameObject("ETerrainParent " + level); var center = pyramidLevelTemplate.Center; parentGO.transform.localPosition = new Vector3(center.x, 0, center.y); var objectsPerRing = pyramidLevelTemplate.PerRingTemplates.Keys.ToDictionary(c => c, c => new List <GameObject>()); GameObject centerObject = null; var ring1ElementMesh = _meshGenerator.AddOrder(() => PlaneGenerator.CreateETerrainSegmentMesh( _perLevelConfiguration.RingObjectMeshVertexLength.X, _perLevelConfiguration.RingObjectMeshVertexLength.Y)).Result; //todo ring1ElementMesh.RecalculateBounds(); MeshGenerationUtils.SetYBounds(ring1ElementMesh, 0f, 1f); foreach (var shapeTemplate in pyramidLevelTemplate.ShapeTemplates) { if (shapeTemplate.RingIndex == 0) //center { var centerMesh = _meshGenerator.AddOrder(() => PlaneGenerator.CreateETerrainSegmentMesh(_perLevelConfiguration.CenterObjectMeshVertexLength.X, _perLevelConfiguration.CenterObjectMeshVertexLength.Y)) .Result; //todo MeshGenerationUtils.SetYBounds(centerMesh, 0f, 1f); centerObject = CreateShapeObject(centerMesh, shapeTemplate, "Center"); centerObject.transform.SetParent(parentGO.transform); } else { var shape = CreateShapeObject(ring1ElementMesh, shapeTemplate, "Ring " + shapeTemplate.RingIndex); shape.transform.SetParent(parentGO.transform); objectsPerRing[shapeTemplate.RingIndex].Add(shape); } } parentGO.transform.localScale = new Vector3(1, _commonConfiguration.YScale, 1); parentGO.transform.SetParent(pyramidRootGo.transform); return(new HeightPyramidSegmentShapeGroup() { CentralShape = centerObject, ParentGameObject = parentGO, ShapesPerRing = objectsPerRing }); }
public void finalizeMesh() { // Call after appending all the components to the mesh, such that the mesh is actually created. // Create the mesh on both the inside and the outside—opposite normals // Such that I don't have to actually compute them, since I have no idea how. mesh.vertices = this.vertices.ToArray(); mesh.normals = this.normales.ToArray(); mesh.uv = this.uvs.ToArray(); mesh.triangles = this.triangles.ToArray(); MeshGenerationUtils.mirrorMesh(mesh); //mesh.RecalculateNormals (); mesh.RecalculateBounds(); mesh.Optimize(); Material material = new Material(Shader.Find("Diffuse")); MeshRenderer meshRenderer = this.gameObject.AddComponent <MeshRenderer> (); meshRenderer.material = material; }
void Start() { MeshFilter meshfilter = gameObject.GetComponentInChildren <MeshFilter>(); // Clone the cloth mesh to work on sourceMesh = new Mesh(); // Get the sourceMesh from the originalSkinnedMesh sourceMesh = meshfilter.mesh; // Clone the sourceMesh workingMesh = MeshGenerationUtils.cloneMesh(sourceMesh); // Reference workingMesh to see deformations meshfilter.mesh = workingMesh; // Apply Laplacian Smoothing Filter to Mesh int iterations = 1; for (int i = 0; i < iterations; i++) { //workingMesh.vertices = SmoothFilter.laplacianFilter(workingMesh.vertices, workingMesh.triangles); workingMesh.vertices = SmoothFilter.hcFilter(sourceMesh.vertices, workingMesh.vertices, workingMesh.triangles, 0.0f, 0.5f); } }
public static Mesh GenerateGrassBladeMesh(int levelsCount) { levelsCount = 7 - levelsCount; Preconditions.Assert(levelsCount >= 1, "levelsCount must be >= 1"); Func <float, float> leftOffsetGenerator = (percent) => { return(1.0f - (float)Math.Pow(-percent + 1.0f, 0.5f)); }; Mesh mesh = new Mesh(); mesh.Clear(); var sw = 1.0f; //standard width var sh = 1.0f; //standard height var df = 0.5f; //decrease factor int vertexCount = 2 * levelsCount + 1; Vector3[] vertices = new Vector3[vertexCount]; Vector2[] uvs = new Vector2[vertices.Length]; for (int currLev = 0; currLev < levelsCount; currLev++) { float height = sh * ((float)currLev / levelsCount); float offsetFromLeft = leftOffsetGenerator((float)currLev / levelsCount) * (sw / 2); var pos1 = new Vector3(offsetFromLeft, height); var pos2 = new Vector3(sw - offsetFromLeft, height); vertices[currLev * 2] = pos1; vertices[currLev * 2 + 1] = pos2; uvs[currLev * 2] = new Vector2(pos1.x, pos1.y); uvs[currLev * 2 + 1] = new Vector2(pos2.x, pos2.y); } vertices[vertexCount - 1] = new Vector3(sw / 2, sh); uvs[vertexCount - 1] = new Vector2(sw / 2, sh); // vertex offset unmaking making for (int i = 0; i < vertices.Length; i++) { vertices[i] -= new Vector3(sw / 2, 0, 0); } Vector3[] normales = new Vector3[vertices.Length]; for (int i = 0; i < vertices.Length; i++) { normales[i] = new Vector3(0.4f, 0.4f, 0.4f); } var trianglesCount = 2 * levelsCount + 1; int[] triangles = new int[3 * trianglesCount]; for (int currLev = 0; currLev < levelsCount - 1; currLev++) { triangles[currLev * 6] = currLev * 2; triangles[currLev * 6 + 1] = currLev * 2 + 1; triangles[currLev * 6 + 2] = currLev * 2 + 3; triangles[currLev * 6 + 3] = currLev * 2; triangles[currLev * 6 + 4] = currLev * 2 + 3; triangles[currLev * 6 + 5] = currLev * 2 + 2; } triangles[3 * trianglesCount - 3] = vertexCount - 3; triangles[3 * trianglesCount - 2] = vertexCount - 2; triangles[3 * trianglesCount - 1] = vertexCount - 1; triangles = MeshGenerationUtils.makeTrianglesDoubleSided(triangles); mesh.vertices = vertices; mesh.normals = normales; mesh.uv = uvs; mesh.triangles = triangles; mesh.RecalculateBounds(); mesh.RecalculateNormals(); ; return(mesh); }
private GrassGroupsPlanter CreateGrassGroupsPlanter(OtherThreadExecutingLocation otherThreadExecutingLocation) { var meshGenerator = new GrassMeshGenerator(); var mesh = meshGenerator.GetGrassBladeMesh(1); MeshGenerationUtils.SetYBoundsToInfinity(mesh); var instancingMaterial = _veConfiguration.ReferencedAssets.GrassMaterial; if (_materialCommonPack != null) { _materialCommonPack.SetToMaterial(instancingMaterial); } var commonUniforms = new UniformsPack(); commonUniforms.SetUniform("_BendingStrength", 0.6f); commonUniforms.SetUniform("_WindDirection", Vector4.one); var gpuInstancerCommonData = new GpuInstancerCommonData(mesh, instancingMaterial, commonUniforms); gpuInstancerCommonData.CastShadows = _veConfiguration.GrassCastShadows; var instancingContainer = new GpuInstancingVegetationSubjectContainer( gpuInstancerCommonData, new GpuInstancingUniformsArrayTemplate(new List <GpuInstancingUniformTemplate>() { new GpuInstancingUniformTemplate("_Color", GpuInstancingUniformType.Vector4), new GpuInstancingUniformTemplate("_InitialBendingValue", GpuInstancingUniformType.Float), new GpuInstancingUniformTemplate("_PlantBendingStiffness", GpuInstancingUniformType.Float), new GpuInstancingUniformTemplate("_PlantDirection", GpuInstancingUniformType.Vector4), new GpuInstancingUniformTemplate("_RandSeed", GpuInstancingUniformType.Float), new GpuInstancingUniformTemplate("_Pointer", GpuInstancingUniformType.Float), }) ); var globalGpuInstancingContainer = _initializationFields.Retrive <GlobalGpuInstancingContainer>(); var bucketId = globalGpuInstancingContainer.CreateBucket(instancingContainer); var grassGroupsContainer = new GrassGroupsContainer(globalGpuInstancingContainer, bucketId); var grassPositionResolver = new SimpleRandomSamplerPositionResolver(); var grassDetailInstancer = new GrassDetailInstancer(); var designBodySpotUpdaterProxy = _initializationFields.Retrive <DesignBodySpotUpdaterProxy>(); var mediatorSpotUpdater = new ListenerCenteredMediatorDesignBodyChangesUpdater(designBodySpotUpdaterProxy); IGrass2AspectsGenerator grassAspectGenerator; if (_veConfiguration.Mode == VegetationMode.Legacy) { grassAspectGenerator = new LegacyGrass2BladeAspectsGenerator(); } else { grassAspectGenerator = new EVegetationGrass2BladeAspectsGenerator(); } var grassGroupsPlanter = new GrassGroupsPlanter( grassDetailInstancer, grassPositionResolver, grassGroupsContainer, mediatorSpotUpdater, grassAspectGenerator, _veConfiguration.GrassTemplates, _veConfiguration.VegetationRepositioner); mediatorSpotUpdater.SetTargetChangesListener(new LambdaSpotPositionChangesListener(null, dict => { otherThreadExecutingLocation.Execute(() => { foreach (var pair in dict) { grassGroupsPlanter.GrassGroupSpotChanged(pair.Key, pair.Value); } return(TaskUtils.EmptyCompleted()); }); })); var rootMediator = _initializationFields.Retrive <RootMediatorSpotPositionsUpdater>(); rootMediator.AddListener(mediatorSpotUpdater); return(grassGroupsPlanter); }