Beispiel #1
0
    void SetMesh()
    {
        if (basemesh)
        {
            // Rebuild verts test
            for (int i = 0; i < barycoords.Length; i++)
            {
                BaryCoord bc = barycoords[i];

                Vector3 bl = Vector3.Lerp(softbody.masses[bc.m[0]].pos, softbody.masses[bc.m[1]].pos, bc.p.z);
                Vector3 tl = Vector3.Lerp(softbody.masses[bc.m[4]].pos, softbody.masses[bc.m[5]].pos, bc.p.z);

                Vector3 br = Vector3.Lerp(softbody.masses[bc.m[3]].pos, softbody.masses[bc.m[2]].pos, bc.p.z);
                Vector3 tr = Vector3.Lerp(softbody.masses[bc.m[7]].pos, softbody.masses[bc.m[6]].pos, bc.p.z);

                Vector3 l = Vector3.Lerp(bl, tl, bc.p.y);
                Vector3 r = Vector3.Lerp(br, tr, bc.p.y);

                verts[i] = Vector3.Lerp(l, r, bc.p.x);
            }

            basemesh.vertices = verts;
            basemesh.RecalculateNormals();
        }
    }
Beispiel #2
0
        override public void TurnDynamics(bool bON)
        {
            if (bON)
            {
                _nposCtrl.TurnON();
            }
            else
            {
                _nposCtrl.TurnOFF();
            }

            foreach (var an in _Anims)
            {
                if (bON)
                {
                    an.enabled = true;
                    an.StartPlayback();
                }
                else
                {
                    an.enabled = false;
                    an.StopPlayback();
                }
            }

            foreach (var crctrl in _crCtrls)
            {
                crctrl.enabled = bON;
            }

            BaryCoord bary = GetComponent <BaryCoord> ();

            bary.enabled = bON;
        }
	// We only need to collision with outside masses so any mass not used 6 times, not if a shell
	// plus we give external links a different stiffness
	// should work from centre of mesh
	// Can easily thread this
	// We have spring builder in my max destruction soft body so use that
	public void VoxelMesh(GameObject obj, float size, bool fill)
	{
		if ( obj == null )
			return;

		voxobj = obj;
		Mesh mesh = MegaUtils.GetMesh(voxobj);
		basemesh = mesh;
		int[]		tris = mesh.triangles;
		Vector3[]	verts = mesh.vertices;


		Vector3 meshsize = mesh.bounds.size;

		xs = Mathf.CeilToInt(meshsize.x / size);
		if ( xs == 0 )
			xs = 1;

		//Debug.Log("ys " + (meshsize.y / size).ToString("0.000"));
		ys = Mathf.CeilToInt(meshsize.y / size);
		if ( ys == 0 )
			ys = 1;

		zs = Mathf.CeilToInt(meshsize.z / size);
		if ( zs == 0 )
			zs = 1;

		origin.x = -((float)xs * 0.5f * size);	//mesh.bounds.min + Jitter;
		origin.y = -((float)ys * 0.5f * size);	//mesh.bounds.min + Jitter;
		origin.z = -((float)zs * 0.5f * size);	//mesh.bounds.min + Jitter;

		// So first check all tris against each cell
		// first get bounds of tri

		// is it quicker to do each tri, get bounds and check those
		// or do each cell and check all tris, (can early out on this)

		// alloc array to hold cell data
		cells = new int[xs, ys, zs];

		// Mmmm looks like a lot quicker otherway for 30 verts on a 4x4x4 we loop 4x4x4x30= 1920
		// if we do tri and get bounds then a lot quicker could be as low as 30 or 2x2x2x30 = 240
		Bounds box = new Bounds();

		int gxs,gxe;
		int gys,gye;
		int gzs,gze;

		Vector3 min = Vector3.zero;

		Vector3 half = new Vector3(size * 0.5f, size * 0.5f, size * 0.5f);
		cellsize = new Vector3(size, size, size);

		//Debug.Log("Origin " + origin.ToString("0.000"));
		for ( int i = 0; i < tris.Length; i += 3 )
		{
			// do bounds on tri
			GetTriBounds(verts, tris, i, origin, out gxs, out gxe, out gys, out gye, out gzs, out gze);

			//Debug.Log("b[" + i + "] " + gxs + " " + gxe + " " + gys + " " + gye + " " + gzs + " " + gze);
			//for ( int z = 0; z < zs; z++ )
			for ( int z = gzs; z <= gze; z++ )
			{
				min.z = origin.z + (z * size);

				//for ( int y = 0; y < ys; y++ )
				for ( int y = gys; y <= gye; y++ )
				{
					min.y = origin.y + (y * size);

					//for ( int x = 0; x < xs; x++ )
					for ( int x = gxs; x <= gxe; x++ )
					{
						min.x = origin.x + (x * size);

						box.SetMinMax(min, min + cellsize);
						//Debug.Log("box " + box.min.ToString("0.000"));
						// build box for cell
						if ( AABB_Triangle_Intersection.TriangleBoxOverlap(verts[tris[i]], verts[tris[i + 1]], verts[tris[i + 2]], box) )
						{
							if ( x < xs && y < ys && z < zs )
								cells[x, y, z] = 1;
							//Debug.Log("hit " + x + " " + y + " " + z);
						}
					}
				}
			}
		}

		// We should have a shell now, so now to fill line by line
		// can do for each axis and combine result (bit per axis) any bit means voxel, this will fill holes

		// Fill it, should do for each axis
		// could be a bug here here cant assume pen changes state in next block, so for pen down we get
		// the first block but we need end of contigous block
		if ( fill )
		{
			for ( int z = 0; z < zs; z++ )
			{
				for ( int y = 0; y < ys; y++ )
				{
					int pd = 0;
					while ( true )	//x != -1 )
					{
						// get pen down
						pd = GetXCell(cells, pd, y, z, xs);
						if ( pd == -1 )
							break;

						// get pen up
						int pu = GetXCell(cells, pd + 1, y, z, xs);

						if ( pu == -1 )
							break;

						for ( int x = pd + 1; x < pu; x++ )
							cells[x, y, z] = 2;
						pd = pu + 1;	// pd is 
					}
				}
			}
		}

		BuildLattice();

		// Build bary coords
		BaryCoord[] barycoords = new BaryCoord[verts.Length];

		for ( int i = 0; i < verts.Length; i++ )
		{
			Vector3 p = verts[i];

			int x = (int)((p.x - origin.x) / CellSize);
			int y = (int)((p.y - origin.y) / CellSize);
			int z = (int)((p.z - origin.z) / CellSize);

			BaryCoord bc = new BaryCoord();
			bc.p.x = (p.x - origin.x - (float)x * CellSize) / CellSize;
			bc.p.y = (p.y - origin.y - (float)y * CellSize) / CellSize;
			bc.p.z = (p.z - origin.z - (float)z * CellSize) / CellSize;

			for ( int c = 0; c < 8; c++ )
			{
				bc.m[c] = GetMassIndex(x, y, z, c);
			}
			//bc.m = FindMassIndex(p);
			//Debug.Log("[" + i + "] " + x + " " + y + " " + z + " " + p);
			barycoords[i] = bc;
		}

		// Rebuild verts test
		for ( int i = 0; i < barycoords.Length; i++ )
		{
			BaryCoord bc = barycoords[i];

			Vector3 bl = Vector3.Lerp(voxmasses[bc.m[0]].p, voxmasses[bc.m[1]].p, bc.p.z);
			Vector3 tl = Vector3.Lerp(voxmasses[bc.m[4]].p, voxmasses[bc.m[5]].p, bc.p.z);

			Vector3 br = Vector3.Lerp(voxmasses[bc.m[3]].p, voxmasses[bc.m[2]].p, bc.p.z);
			Vector3 tr = Vector3.Lerp(voxmasses[bc.m[7]].p, voxmasses[bc.m[6]].p, bc.p.z);

			Vector3 l = Vector3.Lerp(bl, tl, bc.p.y);
			Vector3 r = Vector3.Lerp(br, tr, bc.p.y);

			verts[i] = Vector3.Lerp(l, r, bc.p.x);
		}

		//mesh.vertices = verts;
	}
    // We only need to collision with outside masses so any mass not used 6 times, not if a shell
    // plus we give external links a different stiffness
    // should work from centre of mesh
    // Can easily thread this
    // We have spring builder in my max destruction soft body so use that
    public void VoxelMesh(GameObject obj, float size, bool fill)
    {
        if (obj == null)
        {
            return;
        }

        voxobj = obj;
        Mesh mesh = MegaUtils.GetMesh(voxobj);

        basemesh = mesh;
        int[]     tris  = mesh.triangles;
        Vector3[] verts = mesh.vertices;


        Vector3 meshsize = mesh.bounds.size;

        xs = Mathf.CeilToInt(meshsize.x / size);
        if (xs == 0)
        {
            xs = 1;
        }

        //Debug.Log("ys " + (meshsize.y / size).ToString("0.000"));
        ys = Mathf.CeilToInt(meshsize.y / size);
        if (ys == 0)
        {
            ys = 1;
        }

        zs = Mathf.CeilToInt(meshsize.z / size);
        if (zs == 0)
        {
            zs = 1;
        }

        origin.x = -((float)xs * 0.5f * size);          //mesh.bounds.min + Jitter;
        origin.y = -((float)ys * 0.5f * size);          //mesh.bounds.min + Jitter;
        origin.z = -((float)zs * 0.5f * size);          //mesh.bounds.min + Jitter;

        // So first check all tris against each cell
        // first get bounds of tri

        // is it quicker to do each tri, get bounds and check those
        // or do each cell and check all tris, (can early out on this)

        // alloc array to hold cell data
        cells = new int[xs, ys, zs];

        // Mmmm looks like a lot quicker otherway for 30 verts on a 4x4x4 we loop 4x4x4x30= 1920
        // if we do tri and get bounds then a lot quicker could be as low as 30 or 2x2x2x30 = 240
        Bounds box = new Bounds();

        int gxs, gxe;
        int gys, gye;
        int gzs, gze;

        Vector3 min = Vector3.zero;

        Vector3 half = new Vector3(size * 0.5f, size * 0.5f, size * 0.5f);

        cellsize = new Vector3(size, size, size);

        //Debug.Log("Origin " + origin.ToString("0.000"));
        for (int i = 0; i < tris.Length; i += 3)
        {
            // do bounds on tri
            GetTriBounds(verts, tris, i, origin, out gxs, out gxe, out gys, out gye, out gzs, out gze);

            //Debug.Log("b[" + i + "] " + gxs + " " + gxe + " " + gys + " " + gye + " " + gzs + " " + gze);
            //for ( int z = 0; z < zs; z++ )
            for (int z = gzs; z <= gze; z++)
            {
                min.z = origin.z + (z * size);

                //for ( int y = 0; y < ys; y++ )
                for (int y = gys; y <= gye; y++)
                {
                    min.y = origin.y + (y * size);

                    //for ( int x = 0; x < xs; x++ )
                    for (int x = gxs; x <= gxe; x++)
                    {
                        min.x = origin.x + (x * size);

                        box.SetMinMax(min, min + cellsize);
                        //Debug.Log("box " + box.min.ToString("0.000"));
                        // build box for cell
                        if (AABB_Triangle_Intersection.TriangleBoxOverlap(verts[tris[i]], verts[tris[i + 1]], verts[tris[i + 2]], box))
                        {
                            if (x < xs && y < ys && z < zs)
                            {
                                cells[x, y, z] = 1;
                            }
                            //Debug.Log("hit " + x + " " + y + " " + z);
                        }
                    }
                }
            }
        }

        // We should have a shell now, so now to fill line by line
        // can do for each axis and combine result (bit per axis) any bit means voxel, this will fill holes

        // Fill it, should do for each axis
        // could be a bug here here cant assume pen changes state in next block, so for pen down we get
        // the first block but we need end of contigous block
        if (fill)
        {
            for (int z = 0; z < zs; z++)
            {
                for (int y = 0; y < ys; y++)
                {
                    int pd = 0;
                    while (true)                        //x != -1 )
                    {
                        // get pen down
                        pd = GetXCell(cells, pd, y, z, xs);
                        if (pd == -1)
                        {
                            break;
                        }

                        // get pen up
                        int pu = GetXCell(cells, pd + 1, y, z, xs);

                        if (pu == -1)
                        {
                            break;
                        }

                        for (int x = pd + 1; x < pu; x++)
                        {
                            cells[x, y, z] = 2;
                        }
                        pd = pu + 1;                            // pd is
                    }
                }
            }
        }

        BuildLattice();

        // Build bary coords
        BaryCoord[] barycoords = new BaryCoord[verts.Length];

        for (int i = 0; i < verts.Length; i++)
        {
            Vector3 p = verts[i];

            int x = (int)((p.x - origin.x) / CellSize);
            int y = (int)((p.y - origin.y) / CellSize);
            int z = (int)((p.z - origin.z) / CellSize);

            BaryCoord bc = new BaryCoord();
            bc.p.x = (p.x - origin.x - (float)x * CellSize) / CellSize;
            bc.p.y = (p.y - origin.y - (float)y * CellSize) / CellSize;
            bc.p.z = (p.z - origin.z - (float)z * CellSize) / CellSize;

            for (int c = 0; c < 8; c++)
            {
                bc.m[c] = GetMassIndex(x, y, z, c);
            }
            //bc.m = FindMassIndex(p);
            //Debug.Log("[" + i + "] " + x + " " + y + " " + z + " " + p);
            barycoords[i] = bc;
        }

        // Rebuild verts test
        for (int i = 0; i < barycoords.Length; i++)
        {
            BaryCoord bc = barycoords[i];

            Vector3 bl = Vector3.Lerp(voxmasses[bc.m[0]].p, voxmasses[bc.m[1]].p, bc.p.z);
            Vector3 tl = Vector3.Lerp(voxmasses[bc.m[4]].p, voxmasses[bc.m[5]].p, bc.p.z);

            Vector3 br = Vector3.Lerp(voxmasses[bc.m[3]].p, voxmasses[bc.m[2]].p, bc.p.z);
            Vector3 tr = Vector3.Lerp(voxmasses[bc.m[7]].p, voxmasses[bc.m[6]].p, bc.p.z);

            Vector3 l = Vector3.Lerp(bl, tl, bc.p.y);
            Vector3 r = Vector3.Lerp(br, tr, bc.p.y);

            verts[i] = Vector3.Lerp(l, r, bc.p.x);
        }

        //mesh.vertices = verts;
    }