// // 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)]); } } } }
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(); }
// // 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); }