Exemple #1
0
    //
    // Public methods
    //

    public void evaluateAll(MetaBall[] metaballs)
    {
        if (!this.initized)
        {
            this.init();
        }

        this.vertices.Clear();

        // write info about metaballs in format readable by compute shaders
        GPUBall[] gpuBalls = new GPUBall[metaballs.Length];
        for (int i = 0; i < metaballs.Length; i++)
        {
            MetaBall metaball = metaballs[i];
            gpuBalls[i].position = metaball.transform.localPosition;
            gpuBalls[i].factor   = metaball.factor;
        }

        // magic happens here
        GPUEdgeVertices[] edgeVertices = this.runComputeShader(gpuBalls);
        //根据计算结果,更新所有立方参考体的顶点位置。
        // perform rest of the marching cubes algorithm
        for (int x = 0; x < this.width; x++)
        {
            for (int y = 0; y < this.height; y++)
            {
                for (int z = 0; z < this.depth; z++)
                {
                    this.updateVertices2(edgeVertices[x + this.width * (y + this.height * z)]);
                }
            }
        }
    }
Exemple #2
0
    public void Start()
    {
        List <MetaBall> ballList = new List <MetaBall>();

        for (int i = 0; i < numBalls; i++)
        {
            MetaBall b = GameObject.Instantiate(ballPrefab);
            b.transform.parent        = this.gameObject.transform;
            b.transform.localPosition = Vector3.zero;
            ballList.Add(b);
        }

        ballArray = ballList.ToArray();

        this.grid = new CubeGrid(this, this.computeShader);
    }
    // Update is called once per frame
    void Update()
    {
        if (Input.GetMouseButtonDown(0))
        {
            Ray        ray  = Camera.main.ScreenPointToRay(Input.mousePosition);
            LayerMask  mask = (1 << MetaBallReference.EffectLayer);
            RaycastHit hit;

            if (Physics.Raycast(ray, out hit, 100, mask))
            {
                if (hit.collider.GetComponent <MetaBall>())
                {
                    dragTarget       = hit.collider.GetComponent <MetaBall>();
                    dragTarget.size *= 1.05f;
                }
            }
        }

        if (Input.GetMouseButtonUp(0))
        {
            //Do joining stuff here;
            if (dragTarget)
            {
                foreach (var item in allMetaBalls)
                {
                    if (item != dragTarget)
                    {
                        if (Vector2.Distance(item.position, dragTarget.position) < 2)
                        {
                            // item.transform.parent = dragTarget.transform;
                        }
                    }
                }

                dragTarget.size *= 1 / 1.05f;
            }
            dragTarget = null;
        }

        if (dragTarget)
        {
            dragTarget.transform.position = Vector3.Lerp(dragTarget.transform.position, Camera.main.ScreenToWorldPoint(new Vector3(Input.mousePosition.x, Input.mousePosition.y, 10)), 10 * Time.deltaTime);
        }

        DrawMetaBalls();
    }
Exemple #4
0
    //
    // Public methods
    //

    public void evaluateAll(MetaBall[] metaballs)
    {
        if (!this.initized)
        {
            this.init();
        }

        this.vertices.Clear();

        // write info about metaballs in format readable by compute shaders
        GPUBall[] gpuBalls = new GPUBall[metaballs.Length]; // alloc
        for (int i = 0; i < metaballs.Length; i++)
        {
            MetaBall metaball = metaballs[i];
            gpuBalls[i].position = metaball.transform.localPosition;
            gpuBalls[i].factor   = metaball.factor;
        }

        // magic happens here
#if !ASYNC
        GPUEdgeVertices[] edgeVertices = this.runComputeShader(gpuBalls); // alloc
#else
        this.runComputeShaderAsync(gpuBalls);

        GPUEdgeVertices[] edgeVertices = this.GetEdgeVerticesFromAsync();

        if (edgeVertices == null)
        {
            return;
        }
#endif
        Debug.Log("ev lnt: " + edgeVertices.Length + ", total: " + width * height * depth + ", first index: " + edgeVertices[0].index);

        // perform rest of the marching cubes algorithm
        for (int x = 0; x < this.width; x++)
        {
            for (int y = 0; y < this.height; y++)
            {
                for (int z = 0; z < this.depth; z++)
                {
                    this.updateVertices2(edgeVertices[x + this.width * (y + this.height * z)]);
                }
            }
        }
    }
    public override SurfaceBounds GetSurfaceBounds()
    {
        List <float> max_x_positions = new List <float>();
        List <float> min_x_positions = new List <float>();

        List <float> max_y_positions = new List <float>();
        List <float> min_y_positions = new List <float>();

        List <float> max_z_positions = new List <float>();
        List <float> min_z_positions = new List <float>();

        for (int i = 0; i < MetaBalls.Count; ++i)
        {
            MetaBall meta_ball = MetaBalls[i];

            Vector3 center = meta_ball.transform.position;
            float   radius = meta_ball.Radius;

            float x_position = center.x;
            max_x_positions.Add(x_position + radius);
            min_x_positions.Add(x_position - radius);

            float y_position = center.y;
            max_y_positions.Add(y_position + radius);
            min_y_positions.Add(y_position - radius);

            float z_position = center.z;
            max_z_positions.Add(z_position + radius);
            min_z_positions.Add(z_position - radius);
        }

        return(new SurfaceBounds(
                   new Vector3(
                       max_x_positions.Max(),
                       max_y_positions.Max(),
                       max_z_positions.Max()
                       ),
                   new Vector3(
                       min_x_positions.Min(),
                       min_y_positions.Min(),
                       min_z_positions.Min()
                       )
                   ));
    }
    public override float ComputeFieldDistance(Vector3 point)
    {
        int meta_ball_count = MetaBalls.Count;

        if (meta_ball_count == 0)
        {
            return(Threshold);
        }

        float field_distance = 0.0f;

        for (int i = 0; i < meta_ball_count; ++i)
        {
            MetaBall meta_ball = MetaBalls[i];

            field_distance += meta_ball.Radius / Mathf.Pow((point - meta_ball.transform.position).magnitude, GooFactor);
        }

        return(field_distance);
    }