public void Initialize()
    {
        List <Mesh>         meshList         = new List <Mesh>();
        List <MeshRenderer> meshRendererList = new List <MeshRenderer>();
        List <Transform>    transformList    = new List <Transform>();

        if (GetComponent <Collider>() != null)
        {
            meshList.Add(GetComponent <MeshFilter>().sharedMesh);
            meshRendererList.Add(GetComponent <MeshRenderer>());
            transformList.Add(transform);
        }
        for (int i = 0; i < transform.childCount; i++)
        {
            if (transform.GetChild(i).GetComponent <Collider>() != null)
            {
                Transform child = transform.GetChild(i);

                meshList.Add(child.GetComponent <MeshFilter>().sharedMesh);
                meshRendererList.Add(child.GetComponent <MeshRenderer>());
                transformList.Add(child);
            }
        }

        Mesh[]         meshes        = meshList.ToArray();
        MeshRenderer[] meshRenderers = meshRendererList.ToArray();
        Transform[]    transforms    = transformList.ToArray();

        float[] boundsVolumes = new float[meshes.Length];
        for (int i = 0; i < boundsVolumes.Length; i++)
        {
            boundsVolumes[i] = meshRenderers[i].bounds.size.x * meshRenderers[i].bounds.size.y * meshRenderers[i].bounds.size.z;
        }
        float totalBoundsVolume = boundsVolumes.Sum();

        float[] meshVolumes = new float[meshes.Length];
        for (int i = 0; i < meshVolumes.Length; i++)
        {
            meshVolumes[i] = MeshVolume.VolumeOfMesh(meshes[i], transforms[i]);
        }
        float totalMeshVolume = meshVolumes.Sum();

        Rigidbody rb = GetComponent <Rigidbody>();

        rb.isKinematic = true;
        rb.useGravity  = false;
        rb.mass        = density * totalMeshVolume;
        rb.drag        = 0.0f;
        rb.angularDrag = 0.0f;

        meshSampler = new MeshSampler(meshRenderers, transforms, DistributeSamples(boundsVolumes, totalBoundsVolume) /*, stratifiedDivisions*/);
        gravity     = new Gravity(rb, meshSampler);
        buoyancy    = new Buoyancy(rb, meshSampler, totalMeshVolume);
        waterDrag   = new WaterDrag(rb, meshSampler, viscosity);

        rb.isKinematic = false;
    }
        /// <summary>
        /// Create a TerrainPaint object that paints the passed gameobject. For this to
        /// work, the passed gameobject must have the following components:
        /// MeshFilter, MeshRenderer, and TerrainTile
        /// </summary>
        /// <param name="gameobject">Gameobject to paint</param>
        public TerrainPaint(GameObject gameobject)
        {
            TerrainObject = gameobject;
            Settings      = TerraSettings.Instance;
            SplatSettings = Settings.SplatSettings;


            SetFirstPassShader();
            Mesh = TerrainObject.GetComponent <MeshFilter>().sharedMesh;

            int res = (int)Math.Sqrt(Mesh.vertexCount);

            Sampler = new MeshSampler(Mesh.normals, Mesh.vertices, res);
        }
Exemple #3
0
    void Start()
    {
        List <Vector3> sampled_points = new MeshSampler().sample(m, point_count);


        var particles = new ParticleSystem.Particle[point_count];

        ps.Emit(point_count);
        ps.GetParticles(particles);


        for (int i = 0; i < particles.Length; i++)
        {
            particles[i].position  = sampled_points[i] * scale;
            particles[i].startSize = 0.1f;
        }
        ps.SetParticles(particles, point_count);
    }
Exemple #4
0
        /// <summary>
        /// First creates a poisson grid based on the passed density.
        /// Positions are then filtered based on the passed object placement
        /// type taking into account height and angle constraints.
        ///
        /// Unlike the <c>GetFilteredGrid(ObjectPlacementType, float)</c> method
        /// this method samples from the passed Mesh rather than pulling
        /// mesh information from TerraSettings.
        /// </summary>
        /// <param name="m">Mesh to sample height and angle values from</param>
        /// <param name="type">object placement type to sample</param>
        /// <returns>List of vectors within the grid and sample constraints</returns>
        public List <Vector3> GetFilteredGrid(Mesh m, ObjectPlacementType type)
        {
            MeshSampler    sampler = new MeshSampler(m, Settings.MeshResolution);
            List <Vector2> grid    = GetPoissonGrid(type.Spread / 10);
            List <Vector3> toAdd   = new List <Vector3>();

            foreach (Vector2 pos in grid)
            {
                MeshSampler.MeshSample sample = sampler.SampleAt(pos.x, pos.y);

                if (type.ShouldPlaceAt(sample.Height, sample.Angle))
                {
                    Vector3 newPos = new Vector3(pos.x, sample.Height, pos.y);
                    toAdd.Add(newPos);
                }
            }

            return(toAdd);
        }
        /// <summary>
        /// First creates a poisson grid based on the passed density.
        /// Positions are then filtered based on the passed object placement
        /// type taking into account height and angle constraints.
        ///
        /// Unlike the <c>GetFilteredGrid(ObjectPlacementType, float)</c> method
        /// this method samples from the passed Mesh rather than pulling
        /// mesh information from TerraSettings.
        /// </summary>
        /// <param name="m">Mesh to sample height and angle values from</param>
        /// <param name="objectPlacementData">object placement type to sample</param>
        /// <returns>List of vectors within the grid and sample constraints</returns>
        public List <Vector3> GetFilteredGrid(Mesh m, ObjectPlacementData objectPlacementData)
        {
            MeshSampler    sampler = /**new MeshSampler(m, Settings.Generator.MeshResolution);*/ new MeshSampler(m, 128);          //TODO Resolution from TerraSettings
            List <Vector2> grid    = GetPoissonGrid(objectPlacementData.Spread / 10);
            List <Vector3> toAdd   = new List <Vector3>();

            foreach (Vector2 pos in grid)
            {
                MeshSampler.MeshSample sample = sampler.SampleAt(pos.x, pos.y);

                if (objectPlacementData.ShouldPlaceAt(sample.Height, sample.Angle))
                {
                    Vector3 newPos = new Vector3(pos.x, sample.Height, pos.y);
                    toAdd.Add(newPos);
                }
            }

            return(toAdd);
        }
Exemple #6
0
        public override void OnInspectorGUI()
        {
            base.OnInspectorGUI();

            MeshSampler ms = (MeshSampler)target;

            if (GUILayout.Button("Digest Mesh"))
            {
                ms.DigestMesh();
            }
            if (GUILayout.Button("Sample Random Points"))
            {
                ms.SampleMesh();
            }
            if (GUILayout.Button("Create Spherical Disp Map"))
            {
                ms.CreateSphereDispMap(true);
            }
        }
 public WaterDrag(Rigidbody rb, MeshSampler ms, float viscosity)
 {
     this.rb        = rb;
     this.ms        = ms;
     this.viscosity = viscosity;
 }
Exemple #8
0
 public Buoyancy(Rigidbody rb, MeshSampler ms, float meshVolume)
 {
     this.rb         = rb;
     this.ms         = ms;
     this.meshVolume = meshVolume;
 }
    // Start is called before the first frame update
    void Start()
    {
        Mesh     mesh = Tester.GetComponent <MeshFilter>().sharedMesh;
        Material mat  = Tester.GetComponent <MeshRenderer>().sharedMaterial;

        var tex       = mat.GetTexture("_MainTex") as Texture2D;
        var normalTex = mat.GetTexture("_BumpMap") as Texture2D;

        if (tex == null)
        {
            tex = Texture2D.whiteTexture;
        }

        // Get points on the mesh
        var meshPoints = MeshSampler.SampleRandomPointsOnMesh(mesh, tex, normalTex, PointCount, NoiseLevel);

        // Pick what particles we're going to actually calculate normals for
        var sampleIndices = new NativeList <int>(Allocator.TempJob);
        var rand          = new Random(8976543);

        for (int i = 0; i < meshPoints.Length; ++i)
        {
            if (rand.NextFloat() <= SampleRate)
            {
                sampleIndices.Add(i);
            }
        }

        // Get properties of sampled particles
        var queryPositions = new NativeArray <float3>(sampleIndices.Length, Allocator.TempJob);
        var trueNormals    = new NativeArray <float3>(sampleIndices.Length, Allocator.TempJob);
        var queryColors    = new NativeArray <Color32>(sampleIndices.Length, Allocator.TempJob);

        for (int i = 0; i < sampleIndices.Length; ++i)
        {
            int index = sampleIndices[i];
            queryPositions[i] = meshPoints[index].Position;
            trueNormals[i]    = meshPoints[index].Normal;
            queryColors[i]    = meshPoints[index].Albedo;
        }

        var histograms = PointCloudNormals.CalculateHistograms(meshPoints, queryPositions, trueNormals);

        // Now that we have the hough histograms,
        // we can estimate normals!
        NativeArray <float3> reconstructedNormals;

        if (!UseCNN)
        {
            // Use classical methods
            reconstructedNormals = PointCloudNormals.EstimateNormals(histograms, trueNormals);
        }
        else
        {
            // Pass to CNN!
            reconstructedNormals = PointCloudNormals.EstimateNormalsCNN("TrainingCode/saved_models/tf_model.pb", histograms, trueNormals);
        }

        // Ok we have our properties -> Measure how well we did...
        NativeArray <float> reconstructionError = PointCloudNormals.CalculateScore(reconstructedNormals, trueNormals, out float rms, out float pgp);

        // Log some info about how well we did
        string methodName = UseCNN ? "CNN" : "MaxBin";

        Debug.Log($"{name} finished using {methodName}. Total RMS: {rms}, PGP: {pgp}.");

        // Now visualize it using TC Particles
        var pointCloudData = PointCloudNormals.ConstructPointCloudData(queryPositions, reconstructedNormals, queryColors, ShowErrors, reconstructionError);

        // Write hough textures to disk if requested
        if (WriteData)
        {
            PointCloudNormals.WriteTrainingImages(Folder, CloudName, histograms, trueNormals);
        }

        queryPositions.Dispose();
        trueNormals.Dispose();
        sampleIndices.Dispose();
        queryColors.Dispose();
        reconstructedNormals.Dispose();
        reconstructionError.Dispose();
        histograms.Dispose();

        var system = GetComponent <TCParticleSystem>();

        system.Emitter.PointCloud = pointCloudData;
        system.Emitter.Emit(pointCloudData.PointCount);
        GetComponent <MeshRenderer>().enabled = false;
    }
 public Gravity(Rigidbody rb, MeshSampler ms)
 {
     this.rb = rb;
     this.ms = ms;
 }